必须用语义化标签替代div/span堆砌结构,如导航用、表单控件配、功能图标写有意义alt文本,否则仅靠aria无法解决99%的可访问性问题。

直接改 div 和 span 堆出来的“假语义”结构,不加 ARIA 或换标签,99% 的可访问性问题根本修不干净。
为什么 screen reader 读不出你的“导航栏”
很多遗留 HTML 把导航写成:<div class="nav"><div class="item">首页</div></div>。这在视觉上像导航,但对屏幕阅读器来说就是一堆没意义的 div —— 没角色、没层级、没焦点路径。它不会宣布“导航区域”,也不会把子项识别为可操作项。
- 必须用
<nav></nav>包裹,内部链接用<a></a>(不是<div onclick>) <li>如果用了 JS 控制展开/收起,得补 <code>aria-expanded和aria-controls,且状态要随交互实时更新 - 禁用
role="navigation"手动加在div上——这不是替代方案,是掩盖问题 - 纯装饰图才用
alt="";带功能或含义的图标,必须写有意义的文本,例如:<img src="delete.svg" alt="删除此条记录"> - 如果图是按钮的一部分(比如按钮内含图标+文字),且文字已说明功能,图标可设
alt="",但需确保父按钮有完整可访问名称(aria-label或可见文本) - 避免
alt="icon"、alt="button"这类无信息值——它和没写一样 - 优先用显式
<label for="id">...</label>+<input id="id">配对,ID 必须唯一且匹配 - 嵌套写法也合法:
<label><input type="checkbox"> 接收邮件通知</label>,但要注意内部不能有其他交互元素干扰 - 禁用仅靠 CSS 视觉对齐的“伪 label”——它对辅助技术完全不可见
- 只对原本不可聚焦的元素(如
div)用tabindex="0",让它进入自然流;永远不要用正数tabindex - 隐藏内容该用
aria-hidden="true"+hidden属性,而不是仅靠visibility: hidden或opacity: 0 - 模态框打开时,必须将焦点限制在其中,并在关闭后恢复到触发元素——否则键盘用户会迷失
alt 属性为空但图像有信息怎么办
常见错误是看到图标就填 alt="",结果图标实际承担功能(如“删除”“筛选”“设置”)。空 alt 会让屏幕阅读器跳过,用户完全不知道那里能操作。
表单控件没有关联 label 的硬伤
遗留代码里大量出现:<input type="checkbox"> 接收邮件通知。这种写法导致:键盘用户无法用 Tab 聚焦到文字上,屏幕阅读器不会把文字和输入框绑定,也无法通过点击文字来切换状态。
键盘焦点顺序混乱且跳过关键元素
用鼠标看不出问题,但一按 Tab 就暴露:焦点卡在某个 div 上不动、跳过搜索框、跳进隐藏菜单、或者顺序和视觉流完全相反。根源常是 tabindex="1" 乱用,或 display: none 元素没真正移出 DOM。
最易被忽略的是:可访问性修复不是“加几个属性就完事”。它要求你重新理解每个组件的意图——那个 div 真的是按钮?还是只是视觉分隔?那个“×”图标到底是关闭动作,还是装饰?不厘清这个,所有 aria- 属性都是贴错位置的创可贴。











