:focus-visible

Avatar of Andy Adams
Andy Adams

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

:focus-visible 伪类(也称为“Focus-Indicated”伪类)是一种原生 CSS 方式,用于设置以下元素的样式:

  1. 处于 **焦点** 状态
  2. 需要 **可见** 的指示器来显示焦点(稍后详细介绍)

:focus-visible 的用法与 :focus 相似:吸引用户注意当前拥有焦点的元素。

.element:focus-visible {
  background-color: pink; /* Something to get the user's attention */
}

:focus-visibleCSS4 选择器工作草案 的一部分。在正式规范之前,Mozilla 引入了 :-moz-focusring 伪类,以提前将该功能引入 Firefox。

为什么我们需要 :focus-visible?

:focus 不已经做到这一点了吗?是的,但存在问题。最明显的例子是触发一些 JavaScript 的按钮。想象一个带有按钮来切换图像的图片轮播。假设您已将 tabindex 添加到按钮,以便它们可以通过键盘选择,但当您使用鼠标测试轮播时,您会看到按钮周围有一个轮廓

浏览器在 :focus 上添加的轮廓

当然,您可能不会这样做(出于可访问性考虑),但如何才能摆脱它?通过设置 :focus 伪类

.next-image-button:focus {
  outline: none;
}

现在您的按钮在获得焦点时看起来很棒,但当用户使用键盘而不是鼠标,通过键盘选项卡访问您的按钮时会发生什么?他们看不到自己按了哪个选项卡!这是一个问题,因为现在没有办法判断哪个按钮是键盘操作的焦点

其中一个处于焦点状态,但您看不到!

有没有办法移除蓝色焦点轮廓,但仍然显示更符合站点设计的焦点?当然可以,您可以拥有并享用一切,多亏了 :focus-visible

:focus-visible 仅在您实际**需要**一个视觉指示器来帮助用户看到焦点位置时才适用。换句话说,它不能像 :focus 一样隐藏轮廓。(好吧,它可以通过将轮廓融入设计来隐藏,但无论如何。)从这个意义上来说,这两个必须一起使用。让我们将一个添加到按钮中

.next-image-button:focus {
  outline: none;
}
.next-image-button:focus-visible {
  outline: 3px solid blanchedalmond; /* That'll show 'em */
}

现在,当使用键盘选项卡访问按钮时,将会有一个视觉指示来显示焦点

:focus-visible 使焦点可见!

浏览器如何判断何时某个元素是 :focus-visible?

浏览器可以使用自己的启发式方法来判断何时应将此伪选择器应用于给定元素,从而获得一定的自由度。首先,让我们看看 CSS4 工作草案,然后我们将尝试将其分解。来自 规范

  • 如果用户表达了偏好(例如通过系统偏好设置或浏览器设置来始终显示可见的焦点指示器),则用户代理应该通过使 :focus-visible 始终匹配活动元素来尊重这一点,而不管任何其他因素。(另一个选项可能是用户代理无论作者样式如何,都显示其自己的焦点指示器。)
  • 任何支持键盘输入的元素(例如输入元素,或任何其他可能在获得焦点时触发显示虚拟键盘的元素,如果不存在物理键盘),在获得焦点时应始终与 :focus-visible 匹配。
  • 如果用户通过键盘与页面交互,则当前获得焦点的元素应与 :focus-visible 匹配(即键盘使用可能会改变此伪类是否匹配,即使它不影响 :focus)。
  • 如果用户通过指向设备与页面交互,使得焦点移动到不支持用户输入的新元素,则新获得焦点的元素不应与 :focus-visible 匹配。
  • 如果活动元素与 :focus-visible 匹配,并且脚本导致焦点移动到其他位置,则新获得焦点的元素应与 :focus-visible 匹配。
  • 相反,如果活动元素不与 :focus-visible 匹配,并且脚本导致焦点移动到其他位置,则新获得焦点的元素不应与 :focus-visible 匹配。

如果这有点抽象,这里是一个解释

情况:focus-visible 是否适用?
用户通过设置说他们始终希望焦点可见
一个元素需要键盘才能运行(例如文本 <inputs>)
用户正在使用键盘导航
用户正在使用指向设备(例如鼠标或触摸屏上的手指)导航
脚本导致焦点从 :focus-visible 元素移动到另一个元素
脚本导致焦点从非 :focus-visible 元素移动到另一个元素

需要重复说明:这些只是指南,浏览器将能够自行决定哪些元素被 :focus-visible 选择。我们可以预期键盘导航的明显情况将以可预测的方式处理,但浏览器有能力像其他任何功能一样自行做出决定。

浏览器支持

此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
864*8615.4

移动设备/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712715.4

其他信息