屏幕阅读器依赖语义化html结构,提供段落边界而无语义;标题必须层级连续;alt属性是图像语义强制契约;动态内容需aria-live声明;无障碍核心在于结构连续性与状态同步。

为什么 <p></p> 和 <span></span> 对屏幕阅读器效果差异很大
因为 <p></p> 是语义化块级元素,自带段落停顿和上下文边界;<span></span> 是纯内联容器,无语义,屏幕阅读器默认跳过其存在,只读内容文本。若用 <span></span> 替代 <p></p> 做段落包装,会导致阅读节奏混乱、缺乏结构感知。
实操建议:
- 段落必须用
<p></p>,哪怕只有一句话;避免用<div> 或 <code><span></span>模拟段落 - 强调语气用
<strong></strong>或<em></em>,别用<b></b>/<i></i>—— 后者仅样式,不传达语义强度 - 行内注释或旁白(如“*此处为示例*”)可用
<span aria-label="此处为示例"></span>,但优先考虑改用<aside></aside>或<small></small>+aria-live - 用开发者工具的「Accessibility」面板检查标题树,确认是否连续、嵌套合理
- 视觉上隐藏但逻辑需保留的标题(如页面副标题),用
class="sr-only"(配合position: absolute; clip: rect(0 0 0 0);),而非display: none或visibility: hidden - 禁止用
<h1></h1>做装饰性大字;每个页面有且仅有一个<h1></h1>,代表主内容主题 - 功能性图(如提交按钮的图标)必须写
alt="提交";纯装饰图写alt="";图表/信息图需详述数据趋势,不止“柱状图” - 避免
alt="图片"、alt="logo"这类无效值;logo 若含品牌名,应写alt="Acme 公司标志" - SVG 内嵌时,用
<title></title>+role="img"替代alt,外部 SVG 需加aria-labelledby - 错误消息容器加上
aria-live="polite"(非紧急)或aria-live="assertive"(中断当前语音,如登录失败) - 避免把
aria-live加在频繁刷新的区域(如实时计数器),否则造成语音轰炸;改用aria-relevant="additions text"精确控制 - 表单验证后,聚焦到首个出错字段,并确保该字段有
aria-invalid="true"和关联的aria-describedby指向错误文案
<h1></h1> 到 <h6></h6> 的层级断裂会直接导致导航失效
屏幕阅读器用户常用标题快捷键(如 NVDA 的 H 键)跳转章节。若跳过 <h2></h2> 直接写 <h3></h3>,或嵌套中混用 <h4></h4> 在 <h2></h2> 下却无 <h3></h3>,结构树就断了——阅读器可能跳过该节点,或误判为新主干。
实操建议:
alt 属性不是可选填项,而是图像语义的强制契约
对屏幕阅读器而言,缺失 alt 的 <img> 要么被跳过(装饰图),要么被念成“图片”(信息图),等于丢掉关键信息。而空字符串 alt="" 和无 alt 属性行为不同:前者明确声明“此图无文字意义”,后者是 bug 级疏漏。
实操建议:
动态文本更新(如搜索提示、表单错误)必须触发 aria-live
屏幕阅读器不会自动监听 DOM 变化。JS 插入一段错误提示(如“邮箱格式不正确”)后,若没声明可访问性意图,用户根本听不到——哪怕它在视觉上高亮显示了。
实操建议:
最常被忽略的是:语义标签本身不保证无障碍,关键在「结构连续性」和「状态同步」。比如一个用 <button></button> 实现的下拉菜单,若没管理 aria-expanded 和焦点流,对键盘用户就是死路。细节不在多,而在每个交互节点是否回答了“我现在在哪?能做什么?发生了什么?”











