H5 Web 无障碍基础实践
H5 Web 无障碍基础实践
Web 无障碍要求页面不仅能被鼠标操作,还能被键盘、读屏工具和不同视觉能力的用户使用。很多问题来自语义缺失:用普通元素模拟按钮、表单没有标签、弹窗打开后焦点仍留在背景。优先使用原生语义,再补充必要的 ARIA,通常比从零模拟控件更可靠。
一、使用正确的 HTML 元素
执行动作使用按钮,输入数据使用表单控件,标题保持层级。原生元素已经支持键盘、焦点和读屏角色。
<section aria-labelledby="account-title">
<h2 id="account-title">账户设置</h2>
<button type="button">修改昵称</button>
</section>
不要只为样式方便把所有元素都写成 div,再手动补充一套键盘行为。
二、为表单建立标签关系
<div class="field">
<label for="phone">手机号</label>
<input
id="phone"
name="phone"
type="tel"
aria-describedby="phone-help phone-error"
>
<p id="phone-help">用于接收业务提醒</p>
<p id="phone-error" aria-live="polite"></p>
</div>
占位文本不能代替标签,因为用户输入后它会消失,而且通常对比度较低。
三、保证键盘可操作
用户应能通过 Tab 移动焦点,通过回车或空格触发按钮,并使用方向键操作符合平台习惯的复合控件。
自定义组件如果必须使用普通容器,需要补充角色、焦点和全部键盘交互,成本远高于使用原生元素。
不要使用正数 tabindex 人工排列整页顺序。DOM 顺序应尽量与视觉阅读顺序一致。
四、保留清晰焦点样式
.action-button:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
不能只因为默认轮廓与设计不一致就删除它。可以定制,但必须让焦点在不同背景下清晰可见。
五、弹窗管理焦点
弹窗打开时,应把焦点移动到标题、首个输入或主要操作;弹窗内 Tab 不应进入背景内容;关闭后焦点返回触发按钮。
class DialogFocusManager {
private previousFocus: HTMLElement | null = null;
open(focusTarget: HTMLElement): void {
this.previousFocus = document.activeElement as HTMLElement | null;
focusTarget.focus();
}
close(): void {
this.previousFocus?.focus();
this.previousFocus = null;
}
}
调用方应传入弹窗标题、首个输入或主要按钮等可聚焦元素。完整焦点限制应优先复用项目已有对话框组件,避免每个业务自行处理边界。
六、动态状态需要通知
表单提交结果、加载完成和错误信息可以通过实时区域让读屏用户感知。
<p id="submit-status" aria-live="polite"></p>
高频数据不应持续播报。只通知用户触发的重要变化,并保持文案简洁。
七、图片提供等价文本
有信息含义的图片需要替代文本,描述它传递的内容或功能;纯装饰图形使用空替代文本,避免读屏重复朗读。
图表需要提供摘要、关键数值或可访问的数据表,不能只写“图表图片”。
八、颜色不是唯一线索
错误、涨跌和选中状态应同时使用文字、图标或形状。前景与背景保持足够对比,深色模式和禁用状态单独验证。
链接与普通正文也不能只靠颜色区分,可使用下划线或其他稳定视觉特征。页面正文中无需为了样式取消用户识别习惯。
九、尊重用户显示偏好
减少动态效果设置开启时,应降低非必要位移和缩放。高对比、放大文字和浏览器缩放后,布局仍需可读可操作。
不要禁止页面缩放,也不要通过固定高度裁掉放大后的文本。
十、建立人工与自动测试
自动规则能发现缺少标签、重复标识和部分对比问题,但无法判断替代文本是否准确、焦点流程是否自然。
人工测试至少包括:
- 只用键盘完成核心流程。
- 开启读屏按阅读顺序操作。
- 放大页面后内容不重叠。
- 弹窗焦点进入和返回正确。
- 错误状态既可见又可听。
- 动态内容不会频繁打断用户。
总结
Web 无障碍首先依赖正确语义。使用原生控件、标签和标题层级,保留键盘焦点,管理弹窗与动态通知,再确保信息不只通过颜色传递。公共组件把这些能力内建后,业务页面才能持续保持可访问性。
- 点赞
- 收藏
- 关注作者
评论(0)