无障碍从普通 HTML 就开始。可点击的 div 加一条键盘监听,仍可能缺少名称、角色、焦点行为和禁用状态。优先选语义正确的原生控件,再补充无法从原生语义表达的信息。
名称、关系与顺序
按钮要有说明动作的可访问名称;纯图标按钮可以用 aria-label,但不要写“点击这里”这样脱离上下文的词。输入框使用 label,错误和帮助文字可用 aria-describedby 关联。图片的 alt 按用途决定:传达信息时描述必要信息,纯装饰通常用空 alt,不能简单重复文件名。
DOM 顺序决定很多阅读和键盘顺序。用 CSS order 调换视觉位置后,要检查焦点是否仍沿合理路线移动。不要用正 tabindex 强行拼一套全站顺序。明显的焦点指示有助于键盘用户判断当前位置,不能只为了截图整齐而删除 outline。
弹窗不仅是盖住背景
浏览器原生 dialog 的模态打开方式提供了部分焦点与背景交互行为。仍要给它标题、关闭入口,并在打开和关闭后检查焦点位置。
<button id="open">查看学习提示</button>
<dialog id="help" aria-labelledby="help-title">
<h2 id="help-title">学习提示</h2>
<p>完成练习后,再标记这一节已学。</p>
<form method="dialog"><button>关闭</button></form>
</dialog>
<script>
const opener = document.querySelector("#open");
const dialog = document.querySelector("#help");
opener.addEventListener("click", () => dialog.showModal());
dialog.addEventListener("close", () => opener.focus());
</script>
完整实验页 可检查 Tab、Shift+Tab、Escape、关闭后的焦点。复杂组件库可能自带焦点管理,先读组件契约,避免重复添加陷阱。浏览器及辅助技术组合存在差异,自动检查通过不能替代手动操作与朗读测试。
异步成功可用温和的状态区域通知;不要对每次击键都使用强打断的 alert。错误提示既要可见,也要能与对应字段建立关系。禁用提交按钮应给出可理解原因,不能只改变颜色。
色彩、缩放和动效
普通文字常以 WCAG AA 的 4.5:1 对比度要求检查,大号文字和非文本组件有不同条件。对比度并非全部;颜色之外还需要文字、图标或形状说明状态。200% 缩放、较大系统字体、窄屏和 reduced-motion 都应进入检查。
练习:只用键盘完成新增记录、筛选、打开帮助、关闭帮助四个动作。再使用屏幕阅读器检查标签和状态;若暂时没有完成这一步,应如实记录,不能把自动扫描当作真人朗读验证。
面试自查:aria-label 会如何影响已有的可见名称?为什么 div+click 不等于 button?弹窗关闭后焦点应该去哪里?