button、checkbox、tab 是 ARIA role 值,非原生标签;仅当无法使用原生语义元素时才用 role,且必须手动实现键盘交互、状态同步与焦点管理,否则破坏可访问性。

button、checkbox、tab 这三个不是 HTML 原生标签,而是 ARIA 中定义的 role 值,用于给非语义化元素赋予可访问的交互含义。直接写 <button role="button"> 是冗余且有害的 —— 原生 <button> 已自带正确角色和键盘行为,强行覆盖反而破坏可访问性。
什么时候该用 role="button"
仅当无法使用原生 <button> 元素时才考虑:role="button" 是兜底方案,不是首选。
- 你正在封装一个自定义组件(比如 React 中用
<div>实现的按钮),且不能或不便改用<button> - 必须保留原有 DOM 结构(如 CMS 输出的
<span>),但又需让屏幕阅读器识别为按钮 - 用了
role="button"后,必须手动补全:添加tabindex="0"、监听Enter和Space键、实现aria-pressed(如果是切换按钮) - 错误示范:
<div role="button" onclick="doSomething()">点我</div>—— 缺少键盘支持,会被 AT(辅助技术)忽略或报错
role="checkbox" 的关键约束
它不等于 <input type="checkbox">,而是一个“模拟复选框”的语义声明,只应在完全控制底层状态时使用。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 必须配对使用
aria-checked(值为"true"、"false"或"mixed"),不能靠 class 或 data 属性代替 - 必须关联文字说明:用
aria-labelledby="id"指向一个<label>或其他元素,或用aria-label - 必须响应空格键切换状态(
Enter不触发),并同步更新aria-checked - 禁止套在
<input type="checkbox">外层 —— 原生控件已有完整角色,加role会覆盖其默认行为,导致双倍播报或功能失效
role="tab" 必须配合 role="tablist" 和 role="tabpanel"
单独写 <div role="tab"> 没有意义,ARIA Tab 模式是一整套协作结构,缺一不可。
立即学习“前端免费学习笔记(深入)”;
-
role="tablist"容器必须包含所有tab,且只能有tab子元素(不能混入button或普通文本) - 每个
tab必须有aria-controls="tabpanel-id",指向对应tabpanel的id - 被激活的
tab要设aria-selected="true",其余为"false";对应tabpanel要设aria-hidden="false"(未激活的设为"true") - 键盘导航要求严格:左右箭头切换 tab、
Home/End跳首尾、Enter或Space激活当前 tab —— 这些都得手写 JS 实现
真正容易被忽略的是:ARIA 角色只改语义,不改行为。写了 role="checkbox" 不代表它能被空格切换,写了 role="tab" 不代表它能自动切换面板 —— 所有交互逻辑、焦点管理、状态同步都得自己写,否则对键盘用户和屏幕阅读器就是残障陷阱。


















