tab结构必须用role="tablist"包裹并遵循aria规范:每个tab为,面板为,同步管理aria-selected、hidden及焦点;键盘需支持arrow/ home/end导航,响应式下动态切换角色与行为。

Tab结构必须用role="tablist"包裹,不能只靠CSS模拟
纯CSS实现的Tab(比如用:checked + 隐藏单选框)对屏幕阅读器不可见,键盘也无法聚焦切换。必须用语义化ARIA结构:外层<div role="tablist">,每个Tab项是<code><button role="tab"></button>,对应面板是<div role="tabpanel">。按钮需有<code>aria-controls指向面板ID,面板需有aria-labelledby反向关联Tab按钮ID。
常见错误是漏掉role="tablist"或把Tab写成<a></a>标签——链接默认可聚焦但会触发跳转,且缺少aria-selected状态管理逻辑。
aria-selected和hidden要同步控制,别只靠CSS隐藏
仅用display: none或visibility: hidden隐藏非激活面板,屏幕阅读器仍可能读取内容。正确做法是:非激活Tab按钮设aria-selected="false",对应面板加hidden属性(或aria-hidden="true"),同时移除tabindex="-1";激活面板则设aria-hidden="false"并确保tabindex="0"可聚焦(首次进入时自动聚焦到面板内首个可交互元素更佳)。
要点:
- 每次切换只允许一个Tab的
aria-selected为"true" - 所有非激活面板必须带
hidden,不能只靠CSS - 面板内若含表单控件,切换后需手动
focus()到第一个有效元素
键盘操作必须支持ArrowLeft/ArrowRight和Home/End
ARIA Tab规范要求原生键盘导航:左右箭头在Tab间循环切换,Home跳到第一个,End跳到最后一个。仅靠tabindex顺序无法满足——用户按Tab键会跳出Tablist进入页面其他区域,必须拦截Arrow等事件并手动管理焦点。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
实操建议:
- 给
tablist容器绑定keydown事件,判断e.key是否为"ArrowRight"等 - 维护一个Tab按钮数组,用
Array.prototype.indexOf()找当前焦点索引 - 切换后调用
tabButton.focus(),并同步更新aria-selected和面板hidden - 禁用
Enter和Space的默认行为(按钮本身已处理点击)
不要忽略aria-orientation和响应式断点下的结构退化
横向Tab在小屏可能被挤压换行甚至折叠成下拉菜单,此时role="tablist"语义失效——下拉菜单应改用role="combobox"或role="menu"。必须检测视口宽度,在JS中动态切换ARIA角色和键盘行为。
另一个易忽略点:tablist默认aria-orientation="horizontal",若垂直排列Tab(如左侧导航),必须显式设置aria-orientation="vertical",否则屏幕阅读器仍按水平逻辑播报方向键操作。
复杂点在于:同一套组件在PC和移动设备上可能走两套渲染逻辑,但无障碍属性不能只靠CSS媒体查询控制,必须由JS根据window.matchMedia实时更新DOM属性。










