tabs · 标签页

标签页用于在同一位置切换同层级的几块内容。 键盘行为完全按 APG Tabs Pattern:方向键切换、Home/End 跳首尾。

基本用法(自动激活)

公司名称、代码、行业分类。

切到哪个:基本信息

禁用某个 tab

方向键会跳过禁用的 tab。

按两次 ArrowRight 能到这里(跳过了未开通)。

手动激活(面板内容重时用)

方向键只移动焦点,需按 Enter 才切 —— 读屏不会不停播报。

纵向(设置页侧栏那种)

加 .tabs--vertical,并把 tablist 的 aria-orientation 改成 vertical —— 两件事必须同时做:只改 CSS 的话,键盘仍然是 ← → 切换,而屏幕阅读器被告知"横向", 于是它提示用户按左右键;用户按上下键,没反应。

头像、显示名、所属工作区。

试 ↓ ↑:选中线应该在文字右侧(RTL 下换到左侧)。

键盘契约(APG / Radix)

Tab 进入组时落在当前选中的 tab;再按 Tab 进面板
← → 上一个 / 下一个 tab(并激活)
Home / End 第一个 / 最后一个 tab

roving tabindex:一组 tab 里只有一个是 tabindex="0", 其余全是 -1。否则 Tab 键会逐个穿过所有 tab (一排 5 个要按 5 次)。 更关键的是——那个 "0" 必须跟着选中项走, 只在初始化时设一次是最常见的 bug。

对照:两处最容易写错的地方

❌ 用 div 当 tab

这两个 tab 看起来完全正常,但 <div role="tab"> 根本 Tab 不到(除非手写 tabindex),也不响应 Enter/Space。 APG 要求 tab 是 <button role="tab">。

✅ button role="tab"

同一个外观,键盘行为免费且必然正确。 (这里只演示"能不能聚焦",roving 见下面那块。)

❌ 每个 tab 都写 tabindex="0"

看起来"都能 Tab 到",但一排 3 个 tab 就要按 3 次 Tab 才能进内容区。Tab 键应该是进出控件的, 组内移动是方向键的活。

✅ roving tabindex:整组只有一个 0

一次 Tab 就进来,方向键在组内移动。

那个 0 跟着选中项走 —— 由 roving.js 在切换时搬, 不是初始化时设一次。只设一次是最常见的 bug。