为什么要 A11Y
可访问性不仅服务残障用户,也利好所有人(强光下、单手操作、慢网络转语音)。许多国家/地区还有合规要求。它是质量而非附加项。
清晰的焦点、可读对比、合理标签,对普通用户同样是更好的体验。
语义化优先
无障碍的第一步是用对原生标签:button、nav、main、label 等自带语义与键盘行为,胜过用 div + JS 模拟。
<!-- 反例:div 当按钮,无键盘与语义 -->
<div onclick="submit()">提交</div>
<!-- 正解 -->
<button type="submit">提交</button>ARIA 基础
当原生语义不够(自定义组件)时用 ARIA 补充:role 定义角色,aria-label/aria-expanded 等描述状态。原则是"能原生就别 ARIA"。
<button aria-expanded="true" aria-controls="menu">
菜单
</button>
<ul id="menu" role="menu">...</ul>错误使用 ARIA 比不用更糟。先确保原生语义,再谨慎补充。不要给已有语义的元素强加 role。
键盘可达
所有交互必须能用 Tab/Enter/Esc 完成,焦点要可见且顺序合理。用 :focus-visible 显示清晰焦点环。
:focus-visible { outline: 3px solid #4c8bf5; outline-offset: 2px; }
/* 别用 outline:none 抹掉焦点,会害了键盘用户 */表单与标签
每个输入都要关联 label,错误用 aria-describedby 关联提示,让屏幕阅读器能读出含义与状态。
<label for="email">邮箱</label>
<input id="email" aria-describedby="email-err">
<span id="email-err" role="alert">格式不正确</span>对比度与文字
正文对比度至少 4.5:1,大字号 3:1(WCAG AA)。字号可缩放、行距充足,避免仅靠颜色传达信息。
/* 用相对单位,允许用户缩放 */
body { font-size: 1rem; line-height: 1.6; }
.status { color: #b00; font-weight: 700; } /* 不仅靠颜色,还加粗/图标 */无障碍审计
用 axe DevTools、Lighthouse 自动化检查,配合真实屏幕阅读器(NVDA/VoiceOver)人工走查,覆盖自动化无法发现的问题。
# 在 CI 中跑自动化无障碍测试
npx playwright test --grep a11y
# 或浏览器 DevTools 的 Lighthouse / axe 面板常见陷阱与 FAQ
屏幕阅读器读不出图标。加 aria-label 或用视觉隐藏文本(sr-only),让操作有可读名称。
CSS 里 outline:none 抹掉了焦点环。改用 :focus-visible 给键盘焦点清晰样式,鼠标点击时不打扰。
远非如此。自动化只能发现约 30% 问题。复杂交互、阅读顺序、语义合理性仍需人工+屏幕阅读器验证。