aria不破坏可访问性,但乱用会损害它:role="button"需手动实现键盘交互、焦点和禁用状态;aria-hidden="true"误用于功能性内容将导致不可访问;aria-live需注意更新方式、级别和显示状态;应优先使用原生语义元素。

ARIA 本身不和可访问性冲突,但乱用、误用、覆盖原生语义时,反而会破坏可访问性——这是绝大多数人栽跟头的地方。
为什么 role="button" 比 <button></button> 更容易出问题
原生 <button></button> 自带键盘交互(空格/回车触发)、焦点管理、隐式 aria-disabled 行为和屏幕阅读器识别。而手写 role="button" 的 <div> 不会自动获得这些。
<ul>
<li>必须手动监听 <code>keydown 处理空格/回车,漏掉任一就卡住键盘用户
tabindex="0",否则无法聚焦;禁用时还得同步设 aria-disabled="true" 和 tabindex="-1"
role="button" 又套了 <button></button>,会导致双重角色,部分读屏会重复播报或忽略事件
aria-hidden="true" 和视觉显示不一致时的典型翻车场景
常见于「隐藏但保留功能」的 UI 元素,比如下拉菜单的占位符文字、图标旁的辅助文本、折叠面板的箭头图标。一旦 aria-hidden="true" 加在视觉可见的容器上,屏幕阅读器就彻底跳过它,哪怕里面嵌了 <span>展开</span>。
- 错误写法:
<div aria-hidden="true"> <span>关闭</span><i class="icon"></i> </div>→ 整个区域不可访问 - 正确思路:只对纯装饰性内容隐藏,如图标字体、分隔线;功能性文本必须保留在可访问树中
- 调试技巧:用浏览器 DevTools 的 Accessibility 面板检查「Accessibility tree」是否包含关键文案
用 aria-live 更新内容却没被读出来?检查这三点
aria-live 不是“一设就响”,它的生效依赖更新方式、区域生命周期和读屏策略。
- 动态插入内容必须发生在已挂载的
aria-live容器内,不能先innerHTML = ""再重写——清空操作会中断 live region 的监听上下文 -
aria-live="polite"在读屏忙时会被延迟甚至丢弃;紧急提示建议用aria-live="assertive",但别滥用,否则打断用户操作流 - 避免把
aria-live放在display: none或visibility: hidden的父容器里——即使子元素 visible,live region 也会失效
最常被忽略的其实是「语义优先」原则:能用 <nav></nav> 就别用 role="navigation",能用 <h2></h2> 就别靠 aria-level 硬凑。ARIA 是补丁,不是替代品;补得越勤,越容易盖住底层结构问题。











