焦点指示器
键盘操作时视觉显示当前获得焦点的元素。通常以轮廓或高亮形式呈现。
焦点指示器是在键盘操作时视觉显示当前获得焦点的 UI 元素。通常以轮廓 (边框) 或高亮 (背景色变化) 形式呈现,显示在链接、按钮、表单输入框等交互元素上。对于不用鼠标、仅靠键盘操作网站的用户来说,焦点指示器是把握当前操作位置不可或缺的线索。
WCAG (Web 内容无障碍指南) 2.2 中,与焦点有关的达成标准增加了 3 条。原本就有的达成标准 2.4.7 Focus Visible (AA 级) 要求键盘焦点的位置能够在视觉上得到确认。2.2 新加入的是 2.4.11 Focus Not Obscured (Minimum) (AA 级)、2.4.12 Focus Not Obscured (Enhanced) (AAA 级)、2.4.13 Focus Appearance (AAA 级) 这 3 条。前两条要求固定页眉或 Cookie 横幅这类后来叠上去的元素不得遮挡处于焦点中的元素,AA 级是完全被遮住即不可,AAA 级则连局部被遮住也不可。
对指示器的外观本身课以数值要求的是 2.4.13 Focus Appearance,而它属于 AAA 级。要求有 2 点:一是面积不小于用 2 个 CSS 像素的粗细把非焦点状态下组件的外周围起来所得的面积,二是比较焦点时与非焦点时的同一像素,对比度要在 3:1 以上。常能见到把这里的「2 像素」和「3:1」当成 AA 必须要件递过来的设计指示,但 AA 的范围内要求的只到「看得见」和「不被遮挡」,粗细与比率归在 AAA 一侧,这样切分开来读才准确。
CSS 的 :focus-visible 伪类在焦点指示器的实现中发挥着重要作用。传统的 :focus 在鼠标点击时也会显示焦点环,因此设计师用 outline: none 将其禁用的情况频频发生。改用 :focus-visible,就可以把指示器「什么时候出现」的判断交给浏览器,自己只指定「以什么样子呈现」。判定依据的是浏览器的启发式规则,用键盘移动而获得焦点时会显示,用鼠标点击按钮或链接时通常不显示。这里容易误解的是文本输入框的处理。一直等待输入的元素即使用鼠标点击也会匹配 :focus-visible,所以按「点击时不会出现」的前提来组织设计,就会只有输入框冒出边框,与预想不符。
常见的错误是用 outline: none 或 outline: 0 把焦点指示器完全消掉。在背景色变化、下划线之类的替代视觉变化什么都没准备的情况下就消掉,达成标准 2.4.7 (AA 级) 就无法满足。反过来说,如果消掉轮廓之后用 box-shadow 之类给出了同等以上的表现,那本身并不构成不符合。问题在于「消掉之后什么都不补」。不满意浏览器的默认样式时,应设置与网站设计相称的自定义焦点样式。例如 :focus-visible { outline: 3px solid #4A90D9; outline-offset: 2px; } 这样的指定可以作为出发点。
在设计焦点指示器时,确保在深色模式和浅色模式下都有足够的对比度也很重要。上例中用到的 #4A90D9,对白色 (#FFFFFF) 背景的对比度约为 3.3:1,只是略微超出 3:1 这个参考线的程度。背景换成浅灰 (#E0E0E0) 后会掉到约 2.5:1,反而低于参考线。由于 outline-offset 留出的间隙会让背景色也贴到边框的外周,需要确认的其实是「边框的颜色,与这个边框实际相邻的颜色」之间的关系。选一种明暗背景都撑得住的颜色,或者按模式切换焦点色,才是稳妥的做法。背景色一变,焦点环有时会变得难以看清,因此并用 box-shadow、内侧配明色外侧配暗色做成双重指示器的手法也很有效。此外对于自定义组件 (下拉菜单、模态对话框等),需要用 JavaScript 妥当地实现焦点管理,把焦点陷阱和焦点的恢复正确处理好。
与字符计数相关,焦点指示器在文本输入字段中发挥着特别重要的作用。在像字符计数工具这样拥有多个输入区域的界面中,清楚地显示用户正在输入哪个字段可以防止操作错误,支持高效的文本输入。为活动输入字段设置醒目的焦点指示器直接提升了可用性。