现代 CSS

Web中的焦点管理

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

A11Y中有一个非常重要的点就是关于Web页面或应用上焦点的管理。焦点的管理涉及到多个部分,比如焦点的顺序,焦点的样式等等。这些看上去细微的地方,对于Web的可访问性是非常的重要,特别是对于重度依赖于键盘操作的用户群体来说更为重要,因为焦点的顺序能更这些用户带来更好的体验,另外焦点的样式也能更好的告诉用户现在所处的位置,能有效指导用户在Web上的导航位置。今天和大家一起聊聊Web中有关于焦点方面的知识,如果您感兴趣的话,欢迎继续往下阅读。

什么是焦点

当用户与一个元素进行交互时,浏览器通常会显示一个指示器来表示该元素具有“焦点”。有时也会称之为“焦点环(Focus Ring)”,因为浏览器通常会在焦点元素周置设置一个实心或虚线的边框环。

焦点环向用户发出信号,表明哪个元素将接收键盘事件。如果用户正在浏览一个表单,焦点环会指示他们可以在哪个输入框中输入,或者如果用户已经在一个提交按钮上获得焦点,用户可以直接按键盘的“Enter”或“Space”键盘激活该按钮。

在HTML中,有很多元素称为 可聚焦元素 ,即用户操作Tab键可以让元素获得焦点,带有焦点环效果。

比如上面演示的Facebook的登录界面,其中inputbutton都被称为是可聚焦元素,默认情况之下,客户端会在元素得到焦点的时候给其一个额外的样式(焦点环)样式:

如果你用浏览器的开发者检测器查看代码的话,你会发现,元素在得到焦点时可以使用CSS的:focus给焦点元素设置焦点状态下的样式风格(即,焦点环样式):

Chrome 86引入了两个新功能,在使用焦点时,改善了用户和开发者的体验。比如,新增:focus-visible伪类选择器,它允许开发人员给可聚焦元素设置焦点样式,但只允许用户在使用键盘操作时才显示焦点的元素的焦点环样式。另外还新增了“快速聚焦高亮”的用户首选项,它可以使当前聚焦元素显示一个焦点指示器两秒钟。即使开发者使用CSS禁用了焦点样式,快速焦点高亮也会始终显示。不管用户与页面交互的输入设备是什么,它还会使所有CSS焦点样式相匹配。

焦点问题

对于依赖键盘或其他辅助技术访问Web页面的用户来说,焦点环就像他们的鼠标指针(鼠标指示器)一样。这也是用户知道自己在与什么交互的方式。

不幸的是,许多Web开发者在开Web页面或Web应用时使用CSS样式将可聚焦元素的焦点环都隐藏了。比如:

*:focus {
    outline: none;
}

开发者这样做的原因是因为焦点的底层行为可能很难理解,而对焦点进行样式设计可能会产生令人惊讶的后果。

这样做,虽然满足了设计上的需求(和设计稿效果相匹配),但同时也破坏了依赖键盘访问页面的用户的体验。如前所述,对于依赖键盘访问页面的用户来说,焦点环充当了他们的鼠标指针。因此,去掉焦点环的CSS(不提供替代方案)就相当于隐藏了鼠标指针。

为了改善这种情况,开发人员需要一种更好的方式来处理焦点元素的焦点样式,即一种符合他们对焦点应该如何工作,并且符合用户的期望,也不会给用户带来破坏体验的风险。同时,用户需要在体验中拥有最终发言权,并且应该能够选择何时以及如何看到焦点。这就是:focus-visible和“快速获得高亮”的使用所在。

开发者控制焦点样式的方法

浏览器对于焦点元素都会有一个默认样式,比如拿我们熟悉的<a><button>来说:

我们可以使用开发者工具来查看到它们在获得焦点状态下(:focus)下的样式:

:focus {
    outline: -webkit-focus-ring-color auto 1px;
}

a:-webkit-any-link:focus {
    outline-offset: 1px;
}

也就是说,Web开发者可以显式地使用:focus给可聚焦元素设置焦点状态下的样式(焦点环样式),除此之外,还新增了:focus-visible:focus-within。你在开发者工具中也可以发现这两个新增的伪类选择器:

:focus方式

Web开发者可以使用CSS伪类选择器:focus给可聚焦元素设置焦点样式。当用户点击或触摸元素或通过键盘的Tab键选择它时会被触发。

比如<button>元素:

button:focus {
    outline: 2px dotted #959595;
    outline-offset: 2px;
    box-shadow: 0px 1px 1px #e4e4e4;
}

当用户使用鼠标点击按钮或使用键盘的Tab键选中按钮时,button的样式会产生变化:

也就是说,使用:focus给可聚焦元素设置了样式之后,会告诉浏览器忽略自己给可聚焦元素设置的默认样式,并始终显示你在CSS中:focus状态下的样式。对于某些情况来说,这可能会打破用户的预期,导致混乱的体验。

使用:focus给可聚焦元素设置焦点样式,它有一个副作用,很多人都不喜欢。这意味着当你使用鼠标点击一个可聚焦元素时,会看到焦点样式。但对于使用鼠标的用户来说,他们是不太需要这种反馈(焦点样式),因为你只是把光标移到那里,然后点击一下。不管你怎么想,这些年来,它让很多人很恼火,以至于他们完全删除了焦点样式,这对于Web可访问性来说是一个巨大的损失。

如果我们可以只在使用键盘来聚焦某样东西的时候才应用焦点样式,而不用鼠标呢?是不是给用户能带来更好的一种体验。

:focus-visible

按理说,每个可聚焦元素在元素获得焦点时,浏览器都会给可聚焦元素一个焦点样式。不知道你是否发现,如果我们未显式使用:focus给可聚焦元素设置样式时,我们使用鼠标点击可聚焦元素时,并不会有焦点样式,比如下面这个<button>元素:

但用户使用键盘的Tab键,让<button>元素得到焦点时,会有对应的焦点样式:

但当你使用:focus显式设置焦点元素焦点样式:

button:focus {
    outline: 2px dotted #f36;
    outline-offset: 3px;
}

这个时候,用户不管是使用鼠标点击按钮还是使用键盘的Tab键让<button>获得焦点时,都会有:focus中设置的焦点样式效果:

这样做却失去了浏览器默认状态下可聚焦元素在焦点状态下的指示器。

正如上面提到的,在现代浏览器中,用户使用鼠标点击可聚焦元素,比如<button><a>时不会有焦点样式,但用户按Tab键时,可聚焦元素可以得到焦点样式!

为此,我们可以使用CSS的另一个伪类选择器:focus-visible,这个选择器可以有效地根据用户的输入方式(键盘)展示不同形式的焦点样式。

button:focus-visible {
    outline: 2px solid #f36;
    outline-offset: 2px;
}

这个时候你使用键盘的Tab键,让<button>元素得到焦点时,它的效果如下:

你使用鼠标让<button>得到焦点时,并不会有相应的焦点样式。

我们可以通过将:focus:focus-visible结合起来,可以进一步根据用户的输入设备提供不同的焦点样式:

button:focus {
    outline: 2px dotted #09f;
    outline-offset: 2px;
}

button:focus-visible {
    outline: 2px solid #f36;
    outline-offset: 2px;
}

这个时候不同方式让<button>得到焦点,对应的焦点样式会有所不同,比如下图中左侧是用户按键盘Tab键时,<button>得到焦点时的焦点样式,右侧是用户使用鼠标时,<button>得到焦点时的焦点样式:

不过,:focus:focus-visible也会涉及到选择器权重的问题,就上面的示例来说,如果我们把:focus选择器对应的样式放置到:focus-visible之后:

button:focus-visible {
    outline: 2px solid #f36;
    outline-offset: 2px;
}

button:focus {
    outline: 2px dotted #09f;
    outline-offset: 2px;
}

这个时候,你会发现不管用户使用键盘Tab键还是鼠标让<button>获得焦点时,焦点样式都会采用:focus对应的样式:

如果我们要让:focus:focus-visible可以有独自的样式,可以借助CSS选择器中的:not()来处理:

button:focus:not(:focus-visible) {
    outline: 2px dotted #416dea;
    outline-offset: 2px;
    box-shadow: 0px 1px 1px #416dea;
}

button:focus-visible {
    outline: 2px solid #416dea;
    outline-offset: 2px;
    box-shadow: 0px 1px 1px #416dea;
}

尝试在上面示例中使用键盘的Tab键和鼠标让<button>获得焦点:

:focus-visible启动方式

了解浏览器对焦点指示器的启动方式将有助于我们更好的了解:focus-visible和何时使用:focus-visible。不幸运的是,该启动方式从未被指定,因此在每个浏览器中的行为都有微妙的不同。:focus-visible规范根据浏览器目前渲染行为提出了一种可能的启动主式。

  • 用户是否表示喜欢总是看到焦点指示器:如果用户表示他们总是希望看到焦点指示器,那么:focus-visib
剩余80%内容付费后可查看
返回顶部