aria-pressed专用于切换式按钮(如播放/暂停),需配合role="button"和tabindex="0",监听Space/Enter并同步更新状态;aria-checked用于开关或复选框状态,mixed仅适用于树形结构部分选中;二者不可共存。

aria-pressed 该用在按钮还是开关上
它专为「切换式按钮」设计,比如播放/暂停、加粗/取消加粗这类有明确按下/释放状态的控件。不是所有带点击的元素都适合——aria-pressed 的语义是“当前被按住”,和 button 的 type="button" 或 role="button" 搭配才合理。
常见错误:给 div 加 role="switch" 却用 aria-pressed。这是错的——开关该用 aria-checked;用了 aria-pressed 就得同步管理视觉样式(如背景色、边框)和键盘焦点逻辑(Space 键触发切换)。
- 必须配合
tabindex="0"让非原生按钮可聚焦 - 响应
keydown事件监听Space和Enter,手动切换aria-pressed值 - 不能只靠 CSS :active 伪类——屏幕阅读器不感知它
aria-checked 什么时候必须用 true/false 而不是 mixed
aria-checked="mixed" 只用于「父子项部分选中」的树形或列表结构,比如一个文件夹里部分子文件被勾选。日常单个复选框或单选按钮,永远只用 true 或 false。
容易踩的坑:把表单控件的原生行为和 ARIA 混用。如果用了 <input type="checkbox">,浏览器自动处理 checked 属性和 aria-checked 同步,你不需要手动设 aria-checked;只有自定义渲染的 checkbox(比如用 div + role="checkbox")才需要自己维护 aria-checked 状态。
立即学习“前端免费学习笔记(深入)”;
- 原生
input[type="radio"]不需要aria-checked,它由name组和checked属性驱动 -
aria-checked="mixed"必须配合role="treeitem"或role="option"等容器角色才有意义 - 设置
aria-checked后,记得同步更新视觉标记(✓ 图标、背景色等)
为什么 aria-pressed 和 aria-checked 不能同时出现在同一个元素上
因为它们代表互斥的交互模型:aria-pressed 是瞬时动作反馈(像物理按钮),aria-checked 是持久状态记录(像开关)。WAI-ARIA 规范明确禁止在同一元素上共存这两个属性。
典型误用场景:用 div 实现一个“带状态的按钮”,既想表达“已激活”,又想表达“已选中”。这时候应该先判断控件本质——如果是切换功能(如“静音/取消静音”),用 aria-pressed;如果是选择状态(如“启用通知”),用 aria-checked 并配 role="switch" 或 role="checkbox"。
- 混淆会导致屏幕阅读器播报矛盾信息,例如读成“静音按钮 已按下 已选中”
- 某些辅助技术(如 NVDA)会忽略后设置的属性,行为不可预测
- 测试时可用 axe 浏览器插件检查
aria-*冲突警告
键盘交互没响应?检查 focus 和 keydown 绑定是否漏了
ARIA 状态只是“说清楚”,不负责“做事情”。设了 aria-pressed="true",但没监听 keydown 或没调用 element.focus(),用户用键盘根本切不到、按不了。
尤其注意:自定义控件默认没有 tabindex,也不会响应 Space/Enter。必须显式添加,并在 JS 中接管事件。
- 确保元素有
tabindex="0"(或-1配合程序化聚焦) - 监听
keydown,对Space和Enter都触发状态切换,避免只响应其中一个 - 切换后立即用
element.setAttribute('aria-pressed', newValue)更新,不要只改变量 - 别忘了
preventDefault(),否则Space会触发页面滚动



















