现在花两分钟访问您当前的项目在浏览器中。然后,仅使用 Tab 键,您应该能够在交互式元素之间导航,包括按钮、链接和表单元素。
如果您有视力,您应该能够在 DOM 中看到焦点在元素之间跳转时发生的视觉变化。但是,如果您没有看到任何视觉变化,或者只是看到微不足道的视觉变化,那么您就找到了可以为您的访问者带来巨大差异的一件事。
我们将研究一种使用 CSS 自定义属性使您的焦点样式在整个项目中更易于管理的技术,并了解现代 CSS 焦点选择器。但首先,让我们了解为什么可见焦点样式很重要。
满足 WCAG 焦点样式标准
可见焦点状态在 Web 内容无障碍指南 (WCAG) 成功标准 2.4.7 – 焦点可见中有所涉及。了解 2.4.7 的文档 在此标准的意图中说明了以下内容
此成功标准的目的是帮助用户知道哪个元素具有键盘焦点。必须能够让人知道在多个元素中哪个元素具有键盘焦点。
在即将发布的 WCAG 2.2 中,将添加一个新标准来阐明“焦点指示器应该有多明显”。虽然目前还在草案阶段,但熟悉并应用 2.4.11 – 焦点外观(最小值) 中的指南无疑是您可以采取的积极步骤,可以改进您今天的焦点样式。
使用 CSS 自定义属性管理焦点样式
今年我开始使用的一种技术是在主要基础交互式元素的级联中尽早包含以下设置
:is(a, button, input, textarea, summary) {
--outline-size: max(2px, 0.08em);
--outline-style: solid;
--outline-color: currentColor;
}
:is(a, button, input, textarea, summary):focus {
outline: var(--outline-size) var(--outline-style) var(--outline-color);
outline-offset: var(--outline-offset, var(--outline-size));
}
这将附加自定义属性,使您能够灵活地根据需要仅自定义轮廓样式的某些部分,以确保焦点在元素的上下文发生变化时保持可见。
对于 --outline-size
,我们使用 max()
来确保至少为 2px
的值,同时允许根据 0.08em
相对于组件(例如,标题中的大型按钮或链接)进行缩放。
您可能不熟悉的一个属性是 outline-offset
,它定义了元素与轮廓之间的空间。您甚至可以提供负数来内嵌轮廓,这对于确保焦点样式的对比度非常有用。在我们的规则集中,我们已将该属性设置为接受 --outline-offset
的可选自定义属性,以便根据需要进行自定义,但否则它具有匹配 --outline-size
的回退。
轮廓外观的改进
在我的职业生涯中,我既被要求删除轮廓,也自己删除过轮廓,因为它们被认为是“难看的”。
现在有两个原因,outline
绝对不应该被删除(除了无障碍影响)
outline
现在在 Chromium 和 Firefox 中遵循border-radius
!🎉 这意味着您可以考虑删除您可能使用过的任何黑客,例如使用box-shadow
模拟它(这对无障碍性有另一个积极影响,即确保不会为 Windows 高对比度主题用户删除焦点样式)。- 使用
:focus-visible
,我们可以要求浏览器使用启发式方法仅在检测到需要可见焦点的输入方式时才显示焦点样式。简而言之,这意味着鼠标用户在单击时不会看到它们,键盘用户在选项卡上仍然会看到它们。
需要注意的是,form
元素始终显示焦点样式——它们不受 :focus-visible
行为的影响。
因此,让我们增强我们的规则集,以添加以下内容以包含 :focus-visible
。我们将保留我们已经为旧浏览器定义的初始 :focus
样式,以防万一不会丢失它。
:is(a, button, input, textarea, summary):focus-visible {
outline: var(--outline-size) var(--outline-style) var(--outline-color);
outline-offset: var(--outline-offset, var(--outline-size));
}
由于浏览器处理它们不理解的选择器的方式,我们确实需要将这些规则分开,即使它们定义相同的 outline
属性,也不要将它们合并在一起。
最后,我们还需要这种看起来很奇怪的 :focus:not(:focus-visible)
规则,该规则会为支持 :focus-visible
的浏览器删除常规焦点样式。
:is(a, button, input, textarea, summary):focus:not(:focus-visible) {
outline: none;
}
值得注意的是,最新版本的 Chromium 和 Firefox 已切换到使用 :focus-visible
作为在交互式元素上应用焦点样式的默认方式,并且 最近刚在 webkit 中启用为默认值,因此它应该很快就会出现在 Safari 稳定版中!我们的规则仍然有效,因为我们正在自定义 outline
外观。
有关可见焦点样式的更多指导,我建议您参考 Sara Soueidan 的出色且全面的 焦点指示器指南,因为它考虑了即将到来的 2.4.11 标准。
焦点样式演示
此 Pen 展示了每个交互式元素的示例,以及如何使用自定义属性应用自定义设置,包括一些深色模式的交换。根据您的浏览器支持,您可能看不到焦点样式,因为 :focus-visible
,除非您使用 Tab 键。
最后一点:button
是一个独特的交互式元素,当涉及焦点样式时,因为它在其状态下有额外的注意事项,尤其是在您仅依赖颜色时。有关这方面的帮助,请尝试从我的项目 ButtonBuddy.dev 中使用调色板生成器。
我通常会保留鼠标用户在单击时的焦点样式,因为它在快速查找您在导航回来或关闭选项卡后所处的位置时非常有用,尤其是当链接/按钮位于更长的列表中时。
我认为我需要一个关于如何最好地让我的简单网站在智能手机、鼠标、触控板和键盘输入之间易于访问、直观的并且在一定程度上保持一致的完整教程,而无需针对每个环境分别进行编码、测试和维护。我的头脑在考虑所有这些环境中的焦点、选项卡、悬停和右键单击时都在疼痛。我还有很多东西要学!
这是我在我的个人网站上使用的代码,我想分享一下
就我个人而言,我发现它在美学上更令人愉悦。
PS。它实际上是从 Discord 的 Web 应用程序中借用的,但我已经改进了颜色对比度以实现无障碍性。
更少的键入
更小的文件大小
更高的可读性
否则,您需要将
:focus
、:focus-visible
等添加到每个 HTML 标签选择器中好奇,为什么
:is(a, button, input, textarea, summary) {...}
而不仅仅是
a, button, input, textarea, summary {...}
谢谢!
好问题,Aaron——很可能是由于特异性。
:is
使用其最强的(即最特异的)参数的特异性。这使得在级联中稍后意外覆盖变得更加困难。由于此示例中的所有参数都具有相同的特异性,我认为在这里使用 :is 没有什么好处。
我发现添加 not:(focus-visible) 规则会在 Firefox Developer Edition 96.0b3 中删除之前添加的焦点样式,而不仅仅是浏览器默认样式。
但总的来说,这篇文章非常有帮助。
重要提示:您必须选择在 Firefox 上使用“选项卡聚焦链接”行为;默认情况下,选项卡键会跳过链接。
我总是需要查找如何,因为它有点难以理解。
https://stackoverflow.com/questions/11704828/how-to-allow-keyboard-focus-of-links-in-firefox
留意 ms 高对比度模式,并考虑类似以下内容
还有 Safari 缺乏对
focus-visible
的支持。由于 Safari 目前不支持
:focus-visible
,因此可能需要考虑一种优雅的降级方案,其中我们将focus
指向使用focusVisible
样式(想象一下focusVisible
是 SCSS 世界中的一个 mixin)