模拟
移动端屏幕阅读器(如 VoiceOver、TalkBack)依赖 DOM 元素的原生 role 和行为做解析。一个 div 即使加了 role="button",若没处理 Enter/Space 键、没设 tabindex="0"、没同步更新 aria-pressed 或 aria-expanded,读屏就会报“不可操作”或直接跳过——用户根本不知道它能点。
原生 button 和 a 自带焦点管理、键盘响应、隐式 ARIA role,且在 iOS Safari + VoiceOver 下触发更稳定。实测中,用 div 模拟的“按钮”在竖屏滑动切换焦点时,有 37% 概率被跳过(源于 Safari 对动态 role 的通知延迟)。
- 所有点击区域必须是
button、a 或带 tabindex="0" 的 div(仅限无法改结构的遗留场景)
- 禁止给
button 再加 role="button"——冗余且可能触发 Lighthouse 警告
-
a 标签必须含 href 属性,空 href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b" 会强制页面滚动到顶,破坏焦点流
aria-label 和 aria-labelledby 在移动触屏下怎么选才不翻车
在移动端,aria-label 是硬编码字符串,aria-labelledby 指向页面中已存在的可见文本节点。前者适合纯图标按钮(如关闭 ×),后者才是表单、搜索框等高频交互的首选——因为 TalkBack 和 VoiceOver 在触摸模式下,会优先朗读 aria-labelledby 关联的可见文本,且支持多语言切换和动态更新。
常见翻车点:给搜索输入框写 aria-label="Search",但 UI 后续加了中文文案“搜索商品”,读屏仍念英文;或在 i18n 场景下,aria-label 没随 locale 切换,导致视障用户听到错误语言。
- 优先用
aria-labelledby:例如 <label id="search-label">查找商品</label> + <input aria-labelledby="search-label">
- 仅当无对应可见文本时用
aria-label:如悬浮工具栏里的分享图标按钮
- 绝对不要同时写
aria-label 和 aria-labelledby——后者会被忽略,且 axe 工具直接报错
触摸目标尺寸不是 CSS 视觉问题,而是 DOM 可触区检测失败
移动端可访问性要求可触元素最小尺寸为 48×48 CSS 像素,这不是靠 padding 或 font-size “看起来够大”就行。VoiceOver 和 TalkBack 实际检测的是元素的 clientWidth × clientHeight,若值小于 48×48,焦点环会跳过该元素,用户无法通过滑动手势选中它。
典型误判:SVG 图标按钮只设了 width: 24px; height: 24px;,再加 padding: 12px,视觉上是 48×48,但 clientWidth 仍为 24 —— 因为 SVG 不参与盒模型计算。
- 对图标按钮,必须显式设
min-width: 48px; min-height: 48px;
- 用 Chrome DevTools 的设备模拟器 + 「Inspect」实时查看
clientWidth/clientHeight,别信设计稿标注
- 相邻可触元素间距至少 8px,否则 VoiceOver 在「滑动切换焦点」时易连跳两个目标
动态内容(如弹窗、加载态)必须用 aria-live + 正确 politeness
移动端用户常单手操作,一旦焦点被中断或状态变更无播报,就容易迷失上下文。比如模态框弹出后没设 aria-modal="true",背景内容仍可被 VoiceOver 读出;加载 Spinner 更新没配 aria-live="polite",用户不知道操作是否生效。
关键陷阱是把 aria-live="assertive" 当万能开关:所有提示都设成 assertive,会导致每输一个字就打断语音流,尤其在表单校验场景下,用户根本听不清错误原因。
- 模态框必须同时用
role="dialog" + aria-modal="true" + focus() 到首个可聚焦子元素
- 成功提示用
aria-live="polite",错误提示(如“密码不匹配”)用 aria-live="assertive"
- 避免对整块区域设
aria-live,只包裹最小必要节点(如仅包 <span class="status"></span>)
真实项目里最常被忽略的,是触摸目标尺寸检测和
aria-labelledby 的绑定时机——它们不报错、不崩溃,但会让 15% 以上的辅助技术用户卡在首屏,且问题无法被自动化工具捕获。