原生语义标签比ARIA更可靠,应优先使用<button><nav><main><section>等;aria-label与aria-labelledby不可混用;ARIA属性需JS同步更新;aria-hidden="true"不等于display:none,误用会导致键盘焦点陷阱。

原生语义标签比ARIA更可靠
能用 <button>、<nav>、<main> 就别用 <div role="button"> 或 <div role="navigation">。原生标签自带键盘支持、焦点管理、屏幕阅读器识别,ARIA只是补丁,不是替代品。
常见错误:用 <div class="btn">提交</div> 然后加 role="button" 和 tabindex="0" —— 这样写不仅多出三行代码,还漏掉空格键触发、禁用状态样式、表单提交默认行为等原生能力。
-
<button>自动支持 Enter/Space、disabled、form 关联,无需额外 JS -
<nav>在 NVDA / VoiceOver 中直接读作“导航”,用户可一键跳转 - 用
<section>代替<div class="section">,避免为每个区块手动加role="region"
aria-label 和 aria-labelledby 别混用
同时写 aria-label 和 aria-labelledby 时,浏览器只读 aria-label,后者被静默忽略。这不是叠加增强,是覆盖失效。
正确选择取决于有没有现成的可见文案:
立即学习“前端免费学习笔记(深入)”;
- 纯图标按钮:
<button aria-label="删除第7项"><i class="icon-delete"></i></button>—— 没有视觉文本,只能硬写描述 - 表格操作列:
<label id="row-7-desc">用户张三,邮箱 zhang@example.com</label>+<button aria-labelledby="row-7-desc"><i class="icon-edit"></i></button>—— 复用已有信息,避免重复维护 - 表单字段禁止用
aria-label替代<label>,否则键盘用户无法用标签聚焦输入框
动态组件必须同步更新 ARIA 状态
ARIA 属性本身不改变行为,只传递状态信号。JS 更新 DOM 时,必须同步更新对应属性,否则屏幕阅读器会读错或跳过。
典型场景:
- 下拉菜单:点击按钮后,不仅要显示列表,还得把
aria-expanded="false"改成"true",且列表项必须是role="option"(不能是<li>) - 模态框:打开时设
aria-modal="true"+role="dialog"+aria-labelledby="modal-title",并用.focus()把焦点移到首个可聚焦元素 - 加载中状态:用
aria-busy="true"标记区域,而不是靠 CSS 隐藏后再加aria-hidden="true"—— 后者会让辅助技术彻底“看不见”内容
aria-hidden="true" 不等于 display: none
aria-hidden="true" 是告诉辅助技术“从可访问树里删掉这个节点”,但它还在 DOM 里,仍可被 Tab 键聚焦、仍响应事件。误用会导致键盘用户卡在不可见元素上。
安全用法仅限两类:
- 纯装饰性内容:如
<i class="icon-close" aria-hidden="true"></i>,确认它没绑定 click、没设tabindex、不参与导航 - 模态框开启时隐藏背景:给背景容器加
aria-hidden="true",但必须同步移除其子元素的tabindex或设为-1;更推荐用inert属性(现代浏览器支持)
绝对禁止:给整个弹窗外层容器加 aria-hidden="true" 却忘了在打开时切回 false,结果弹窗内容对屏幕阅读器彻底不可见。



















