应使用 role="list"/role="listitem" 替代 div 布局列表,确保语义正确;可点击项须用原生 button 并设 aria-label;导航当前页用 aria-current="page";触摸目标需 ≥44×44px 且间距充足。

用 role="list" 和 role="listitem" 替代纯 div 布局列表
原生 ul/li 在 VoiceOver 或 TalkBack 中能被自动识别为列表并播报项数(如“列表,共 5 项”),但很多移动端 UI 为样式可控改用 div + Flex 布局,导致屏幕阅读器完全跳过结构语义。手动补 role 是最轻量的修复方式。
实操建议:
- 避免写
<div class="list"><div class="item">…</div></div>,改用<div role="list"><div role="listitem">…</div></div> - 必须确保
role="listitem"直接子于role="list",嵌套div会中断语义链 - 若列表含可点击项(如新闻卡片),在
role="listitem"上加tabindex="0"并监听keydown的Enter/Space,否则盲人用户无法键盘激活
按钮必须用 <button></button>,禁用 div + onclick 模拟
用 div 绑定 onclick 的“按钮”,在盲人模式下既不进 Tab 键盘流,也不被识别为可操作控件,VoiceOver 会读作“静态文本”或直接跳过。
实操建议:
- 所有触发操作的元素,优先用原生
<button type="button"></button>;表单提交用type="submit" - 若需自定义样式,用 CSS 重置
button默认外观(appearance: none、去除边框/背景等),而非弃用标签 - 禁用
div上加tabindex="0"+role="button"的“补救方案”——它无法响应空格键,且 iOS VoiceOver 对role="button"支持不稳定 - 图标按钮必须加
aria-label,例如<button aria-label="删除此条目"><svg>…</svg></button>
aria-current="page" 比 CSS 类更可靠地标记当前导航项
移动端底部导航栏常靠 class="active" 控制高亮,但屏幕阅读器看不到 CSS 类。若不声明当前页状态,盲人用户无法确认自己所处位置。
实操建议:
- 在当前选中的导航
button或a上添加aria-current="page"(不是"true") - 避免混用
aria-current="true"—— 这是无效值,部分旧版 TalkBack 会忽略 - 配合
aria-label强化意图,例如<button aria-current="page" aria-label="当前页面:首页">?</button> - 服务端渲染时动态注入该属性,不要依赖 JS 后续添加——首屏加载后才挂载会导致初始焦点丢失上下文
触摸目标尺寸不足 44×44px 是硬伤,min-height 和 padding 都得算进去
WCAG 要求可点击区域 ≥ 44×44 CSS 像素,但很多团队只看视觉尺寸。实际触摸热区由浏览器根据 content-box 尺寸计算,border 和 margin 不计入。
实操建议:
- 检查 DevTools 的 “Computed” 面板中
height+padding-top+padding-bottom≥ 44px,width+ 横向内边距同理 - 对图标按钮,用
padding扩展热区,而非仅放大 SVG 尺寸——后者易导致模糊且不增加可触面积 - iOS Safari 会自动将
button最小高度提升至 44px,但 Android Chrome 不会,必须显式设置 - 避免用
transform: scale()伪增大——热区仍按原始尺寸计算
最常被忽略的是:列表项内多个操作按钮(如“编辑”“删除”)挤在一起时,即使单个达标,间距不足也会导致误触,此时需用 gap 或 margin 确保相邻热区中心距 ≥ 44px。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











