标准 · ARIA

角色 文档结构

tabpanel

标记与某个标签页配对的内容面板。每个 tabpanel 通过 aria-labelledby 由其对应的 tab 命名;tab 则通过 aria-controls 引用该面板。每次仅显示一个面板,其余面板使用 hidden 属性隐藏。

适用场景

用于承载某个标签页内容的容器。通过 aria-labelledby 将每个 tabpanel 与其对应的 tab 关联(指向 tab 的 id);tab 则通过 aria-controls 反向指向面板,形成互指关系。应使用 hidden 属性隐藏非激活面板——而非仅通过 CSS 设置 display: none——以确保无障碍树与视觉状态保持一致。

若面板包含交互内容(如表单、链接列表),可通过 tabindex="0" 使面板可聚焦。这样,激活标签页后,下一次按 Tab 键焦点将落入面板内部。

若面板内只有一个可聚焦区域——例如一个大标题后跟随内容——在面板上设置 tabindex="0" 即可。若面板内包含大量可聚焦控件,用户可直接 Tab 至这些控件,tabindex 则为可选项。

常见错误

  • 通过 CSS 隐藏 tabpanel,但未设置 hidden 属性。屏幕阅读器仍可能暴露其内容。
  • tabpanel 缺少 aria-labelledby——将被播报为”标签面板”,没有名称。
  • tab 通过 aria-controls 指向 tabpanel 的 id,但面板未通过 aria-labelledby 反向指回 tab。两者的关联必须互相对应。
  • 所有 tabpanel 保留在 DOM 中,仅通过动态切换 display: none 来隐藏,但未设置 hidden 属性。审计人员会将此标记为不一致。
  • role="tabpanel" 应用于未与 role="tab" 配对的面板——形成孤立的 tabpanel。

示例

<div role="tablist" aria-label="Settings">
  <button role="tab" id="t-account" aria-selected="true"  aria-controls="p-account" tabindex="0">Account</button>
  <button role="tab" id="t-billing" aria-selected="false" aria-controls="p-billing" tabindex="-1">Billing</button>
</div>

<section role="tabpanel" id="p-account" aria-labelledby="t-account" tabindex="0">
  <h2>Account</h2>
  <p>…</p>
</section>
<section role="tabpanel" id="p-billing" aria-labelledby="t-billing" tabindex="0" hidden>
  <h2>Billing</h2>
  <p>…</p>
</section>