角色 复合控件
tablist
将容器标记为选项卡界面中的标签条。其子元素为 role="tab"。标签页与 tabpanel 是纯 ARIA 模式——HTML 中没有原生的 tablist 元素。
适用场景
用于包裹选项卡界面中 role="tab" 元素所在的行(或列)。tablist 必须通过 aria-label 或 aria-labelledby 提供无障碍名称——若缺少名称,屏幕阅读器用户听到”标签列表”时无法判断页面上具体是哪个 tablist。
垂直标签条需设置 aria-orientation="vertical"。默认方向为水平,水平标签页可省略该属性。
如果所谓的”标签页”实际上是跳转至不同 URL 的导航,应改用带 <a> 链接的 <nav> 元素——点击即改变 URL 的模式与 tablist 语义不符。
键盘与焦点规范
依据 APG 标签页模式:
- Tab 键将焦点移入 tablist,定位到当前选中的标签页;再次按 Tab 键将焦点移出(通常进入激活的 tabpanel)。
- 左右方向键在标签页之间移动焦点(垂直 tablist 则为上下方向键);是否支持循环可选,但属常规惯例。
- Home / End 键跳转至第一个或最后一个标签页。
- 激活方式:自动模式下,方向键既移动焦点也同步选中;手动模式(激活操作较耗时时推荐)下,需按 Space 或 Enter 选中当前聚焦的标签页。
tablist 本身不处理焦点——焦点落在 tab 上,而非 tablist 容器上。
常见错误
- tablist 没有无障碍名称。页面上存在多个 tablist 时,彼此无法区分。
- 所有标签页均设置
tabindex="0"。该模式为单 Tab 停靠点,仅当前选中的标签页设置tabindex="0"。 - 垂直 tablist 缺少
aria-orientation="vertical"——屏幕阅读器会提示用户使用左右方向键,但视觉布局要求的是上下方向键。 role="tablist"包裹的是链接(<a href="#section">)而非按钮。锚点会使页面滚动并破坏退后按钮的行为。- tabpanel 同时使用
display: none和hidden属性隐藏,其中一种已足够。
示例
<div role="tablist" aria-label="Project sections" aria-orientation="horizontal">
<button role="tab" id="t-overview" aria-selected="true" aria-controls="p-overview" tabindex="0">Overview</button>
<button role="tab" id="t-files" aria-selected="false" aria-controls="p-files" tabindex="-1">Files</button>
<button role="tab" id="t-team" aria-selected="false" aria-controls="p-team" tabindex="-1">Team</button>
</div>