这将是我们关于表单无障碍的小系列的第二篇文章。如果您错过了第一篇文章,请查看 使用伪类构建无障碍表单。在这篇文章中,我们将研究 :focus-visible 以及如何在您的网站中使用它!
焦点触点
在我们继续使用 :focus-visible
之前,让我们回顾一下 :focus
在您的 CSS 中是如何工作的。焦点是元素通过键盘、鼠标、触控板或辅助技术进行交互时的视觉指示器。某些元素天生具有交互性,例如链接、按钮和表单元素。我们希望确保我们的用户知道他们在哪里以及他们正在进行的交互。
请记住,不要在您的 CSS 中这样做!
:focus {
outline: 0;
}
/*** OR ***/
:focus {
outline: none;
}
当您删除焦点时,您会为所有人删除它!我们希望确保我们保留焦点。
如果出于任何原因您确实需要删除焦点,请确保还为您的用户提供备用 :focus
样式。该备用样式可以匹配您的品牌颜色,但请确保这些颜色也是无障碍的。如果市场营销、设计或品牌不喜欢默认的焦点环样式,那么是时候开始与他们进行对话,并就最佳的添加方式进行协商了。
focus-visible?
什么是 伪类 :focus-visible
就像我们的默认 :focus
伪类一样。它为用户提供了一个指示器,表明页面上某个元素正在被聚焦。编写 :focus-visible
的方法非常直截了当
:focus-visible {
/* ... */
}
在使用 :focus-visible
与特定元素时,语法类似于以下示例
.your-element:focus-visible {
/*...*/
}
使用 :focus-visible
的好处是,您可以让您的元素脱颖而出,明亮而醒目! 不用担心它在元素被点击/点击时显示。如果您选择不实现该类,则默认情况是用户代理焦点环,而这对于某些人来说是不可取的。
focus-visible
的背景故事
在 :focus-visible
出现之前,用户代理样式会将 :focus
应用于页面上的大多数元素;按钮、链接等。它会将轮廓或“焦点环”应用于可聚焦元素。这被认为是丑陋的,大多数人不喜欢浏览器提供的默认焦点环。由于焦点环看起来不太好,因此大多数作者都将其删除了……却没有提供备用样式。请记住,当您删除 :focus
时,会降低可用性,并使键盘用户体验变得无法访问。
在当前的网络状态下,当元素获得焦点时,浏览器不再在各种元素周围明显地指示焦点。 相反,浏览器使用不同的启发式方法来确定何时会对用户有所帮助,并提供一个焦点环作为回报。根据 可汗学院 的说法,启发式方法是指“引导算法找到良好选择的技巧”。
这意味着浏览器可以检测到用户是否正在通过键盘、鼠标或触控板与体验进行交互,并根据该输入类型添加或删除焦点环。这篇文章中的示例突出了输入交互。
在 :focus-visible
的早期阶段,我们使用了 polyfill 来处理 Alice Boxhall 和 Brian Kardell 创建的焦点环,Mozilla 也推出了自己的伪类 :moz-focusring
,然后才是正式规范。如果您想了解有关焦点环早期阶段的更多信息,请查看 A11y Casts,由 Rob Dodson 主持。
焦点的重要性
您的应用程序中焦点很重要的原因有很多。其中一个原因,正如我上面提到的,作为网络的使者,我们必须确保提供最好的、最无障碍的体验。我们不希望任何用户在浏览体验时猜测自己的位置。
一个总是会想到的例子是 Two Blind Brothers 网站。如果您访问该网站并点击/点击(这在移动设备上有效)左下角的闭眼,您将看到眼睛睁开,并开始模拟。两兄弟 Bradford 和 Bryan Manning 在很小的时候就被诊断出患有 Stargardt 病。Stargardt 病是一种眼部黄斑变性的形式。随着时间的推移,两兄弟将完全失明。访问该网站并点击眼睛,看看他们是如何看到的。
如果您身处他们的位置,并且必须浏览一个页面,您将希望确保在整个体验过程中完全知道自己的位置。焦点环能为您提供这种力量。

演示
下面的演示显示了将 :focus-visible
添加到您的 CSS 中时的工作原理。视频的第一部分显示了使用鼠标浏览体验时的效果,第二部分显示了只使用键盘浏览时的效果。我还记录了自己的操作,以显示我确实从使用鼠标切换到了使用键盘。

浏览器根据我的输入(键盘/鼠标)预测要对焦点环执行的操作,然后将焦点环添加到这些元素中。在本例中,当我使用键盘浏览此示例时,所有内容都会获得焦点。当使用鼠标时,只有输入会获得焦点,而按钮不会。如果您删除 :focus-visible
,浏览器将应用默认的焦点环。
下面的代码将 :focus-visible
应用于可聚焦元素。
:focus-visible {
outline-color: black;
font-size: 1.2em;
font-family: serif;
font-weight: bold;
}
如果您想指定 label
或按钮以接收 :focus-visible
,只需分别在类前面加上 input
或 button
即可。
button:focus-visible {
outline-color: black;
font-size: 1.2em;
font-family: serif;
font-weight: bold;
}
/*** OR ***/
input:focus-visible {
outline-color: black;
font-size: 1.2em;
font-family: serif;
font-weight: bold;
}
支持
如果浏览器不支持 :focus-visible
,您可以启用一个备用方案来处理交互。下面的代码来自 MDN Playground。您可以使用 @supports at 规则或“功能查询”来检查支持。请记住,该规则应该放置在代码的顶部,或者嵌套在另一个组 at 规则中。
<button class="button with-fallback" type="button">Button with fallback</button>
<button class="button without-fallback" type="button">Button without fallback</button>
.button {
margin: 10px;
border: 2px solid darkgray;
border-radius: 4px;
}
.button:focus-visible {
/* Draw the focus when :focus-visible is supported */
outline: 3px solid deepskyblue;
outline-offset: 3px;
}
@supports not selector(:focus-visible) {
.button.with-fallback:focus {
/* Fallback for browsers without :focus-visible support */
outline: 3px solid deepskyblue;
outline-offset: 3px;
}
}
其他无障碍问题
在构建体验时需要牢记的无障碍问题
- 确保您为焦点指示器选择的颜色(如果有的话)仍然是无障碍的,符合 WCAG 2.2 非文本对比度(AA 级) 中记录的信息
- 认知超负荷会导致用户压力。请确保各种交互元素的样式保持一致
浏览器支持
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器在该版本及更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
86 | 4* | 否 | 86 | 15.4 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 15.4 |
鉴于大多数不支持
:focus-visible
的浏览器也不支持@supports not
,一个更好的回退是使用:focus
设置焦点样式,然后使用:focus:not(:focus-visible)
选择器删除它们和默认值。我更喜欢对
:focus-visible
使用box-shadow
,并使用一个透明的outline
,这样它将在 Windows 高对比度模式下运行良好。以下是一个示例 - https://github.com/basher/Web-UI-Boilerplate/blob/master/ui/src/stylesheets/mixins/_focus.scss#L46
听起来是个不错的主意。
感谢分享!
我现在确信可以在我的代码中很好地使用它,没有任何疑问。
:has 给我们带来了 :focus-visible-within,即使它在 CSS 中不是官方的。这对那些复杂的组件很有用。
:has(*:focus-visible)
很棒的文章。它对我的工作帮助很大。感谢分享这些有效且有用的方法。
找到了新的工作方式,感谢分享