标准 HTML 元素(例如 <button>
或 <input>
)内置了键盘无障碍功能,应尽可能使用。不过,如果您需要构建自定义交互元素,可以通过添加 tabindex
来创建预期的用户行为。
请仅向互动内容添加 tabindex
。即使内容很重要(例如关键图片),屏幕阅读器用户也无需添加焦点即可理解它。
什么是 tabindex?
如果您需要修改内置元素提供的默认标签页顺序,可以使用 tabindex
HTML 属性来明确设置元素的标签页位置。
tabindex
可应用于任何元素,但应仅应用于交互式元素,并采用一系列整数值。借助 tabindex
,您可以为可聚焦的页面元素指定显式顺序,将原本不可聚焦的元素插入到标签页顺序中,以及从标签页顺序中移除元素。例如:
tabindex="0"
:将元素插入到自然标签页顺序中。您可以通过按 Tab 键将焦点移至该元素,也可以通过调用其 focus()
方法将焦点移至该元素。
tabindex="-1"
:从自然标签页顺序中移除元素,但您仍然可以通过调用其 focus()
方法来将焦点移至该元素
tabindex="5"
:任何大于 0
的 tabindex 都会将相应元素移至自然标签页顺序的前面。如果有多个元素的 tabindex 大于 0
,则 tab 顺序从大于零的最低值开始,逐渐增加。使用大于 0
的 tabindex 被视为反模式。
确保控件可通过键盘访问
Lighthouse 等工具非常擅长自动检测某些无障碍功能问题,但有些测试仍需由人工手动完成。
请尝试按 Tab
键浏览您的网站。您能否触及页面上的所有交互控件?如果没有,您可能需要使用 tabindex
来提高这些控件的可聚焦性。
在页面级别管理焦点
有时,tabindex
有助于打造顺畅的用户体验。例如,如果您构建了一个包含不同内容部分的强大单页,其中某些内容会在网页加载的不同时间点隐藏。这可能意味着导航链接会更改可见内容,而无需刷新网页。
在本例中,识别所选内容区域,并为其指定 tabindex
为 -1
,然后调用其 focus
方法。这样可以确保内容不会显示在自然的标签页顺序中。此技术称为管理焦点,可确保用户感知的上下文与网站的视觉内容保持同步。
管理组件中的焦点
在某些情况下,您还必须在控件级别管理焦点,例如使用自定义元素时。
确定要实现哪些键盘行为可能很难。Accessible Rich Internet Applications (ARIA) Authoring Practices 指南列出了组件类型及其支持的键盘操作类型。
将元素插入到标签页顺序中
使用 tabindex="0"
将元素插入自然标签页顺序中。例如:
<div tabindex="0">Focus me with the TAB key</div>
如需将焦点移至某个元素,请按 Tab
键或调用该元素的 focus()
方法。
从标签页顺序中移除元素
使用 tabindex="-1"
移除元素。例如:
<button tabindex="-1">Can't reach me with the TAB key!</button>
这会将元素从自然标签页顺序中移除,但您仍然可以通过调用其 focus()
方法来将焦点移至该元素。
对元素应用 tabindex="-1"
不会影响其子元素;如果它们自然而然地或因 tabindex
值而位于标签页顺序中,则会保持在标签页顺序中。如需从标签页顺序中移除某个元素及其所有子元素,请考虑使用 WICG 的 inert
polyfill。该 polyfill 会模拟建议的 inert
属性的行为,以防止辅助技术选择或读取元素。
避免使用 tabindex > 0
任何大于 0 的 tabindex
都会将元素跳转到自然标签页顺序的前面。如果有多个元素的 tabindex
大于 0,则标签页顺序从大于 0 的最低值开始,逐渐递增。
使用大于 0 的 tabindex
被视为反模式,因为屏幕阅读器会按 DOM 顺序(而非标签页顺序)浏览网页。如果您需要某个元素在标签页顺序中显示得更早,则应将其移至 DOM 中的更前的位置。
借助 Lighthouse,您可以识别 tabindex
> 0 的元素。运行无障碍功能审核(Lighthouse > 选项 > 无障碍功能),然后查看“所有元素的 [tabindex]
值都不大于 0”审核的结果。
使用“流动 tabindex
”
如果您要构建复杂的组件,除了焦点之外,可能还需要添加额外的键盘支持。请尽可能使用内置的 select
元素。它可获得焦点,并且允许使用箭头键显示其他可选选项。
如需在您自己的组件中实现类似的功能,您可以使用一种称为“巡回 tabindex
”的技术。巡回 tabindex 的运作方式是,将当前处于活动状态的子项以外的所有子项的 tabindex
设置为 -1。然后,该组件使用键盘事件监听器来确定用户按下了哪个键。
在这种情况下,组件会将之前获得焦点的子项的 tabindex
设置为 -1,将要获得焦点的子项的 tabindex
设置为 0,并对其调用 focus()
方法。
之前
<div role="toolbar">
<button tabindex="-1">Undo</button>
<button tabindex="0">Redo</button>
<button tabindex="-1">Cut</button>
</div>
之后
<div role="toolbar">
<button tabindex="-1">Undo</button>
<button tabindex="-1">Redo</button>
<button tabindex="0">Cut</button>
</div>
键盘访问权限方案
如果您不确定自定义组件可能需要哪种级别的键盘支持,可以参阅 ARIA 编写实践 1.1。本指南列出了常见的界面模式,并确定了组件应支持哪些按键。