关键在于让视觉提示、焦点行为与屏幕阅读器播报协同一致:实时同步aria-invalid状态,用aria-describedby指向唯一id的错误文案容器,并配合css样式与自动聚焦形成闭环。

在 H5 表单中,把自定义校验提示和无障碍访问(a11y)真正结合好,关键不是只加 aria-invalid="true" 或只写个 aria-describedby,而是让两者协同工作:视觉提示、焦点行为、屏幕阅读器播报三者一致。下面分几步讲清楚怎么做。
确保校验状态与 aria-invalid 实时同步
aria-invalid 必须准确反映字段当前是否校验失败,不能靠 CSS 类或 JS 变量“猜”。推荐在输入事件(input、blur)触发校验后,直接设置属性:
- 校验失败时:
inputEl.setAttribute('aria-invalid', 'true') - 校验通过或清空时:
inputEl.setAttribute('aria-invalid', 'false')(注意:不要移除该属性,设为false才符合规范) - 避免用
aria-invalid="grammar"等值——除非你真做了语法级校验,否则统一用"true"或"false"
用 aria-describedby 指向唯一、可读的错误文案容器
aria-describedby 的作用是告诉屏幕阅读器:“这个输入框的错误说明在哪儿”。它必须指向一个**真实存在的、有明确 ID 的元素**,且该元素内容要简洁、主动、可操作:
- 错误提示容器需有
id(如id="email-error"),且放在表单内、紧邻输入框附近(DOM 顺序建议在 input 下方) - 给 input 设置:
aria-describedby="email-error"(多个 ID 用空格分隔,如需同时关联帮助文本) - 错误文案本身不要写“错误:”开头(屏幕阅读器已通过
aria-invalid知道这是错误),直接说清问题,例如:“请输入有效的邮箱地址”而非“错误:邮箱格式不正确” - 该容器初始应
hidden或aria-hidden="true",校验失败时移除隐藏并确保可聚焦(但通常不需tabindex,因为aria-describedby会自动播报)
配合视觉样式与焦点管理,形成完整反馈闭环
仅靠 ARIA 属性无法完成无障碍体验。必须同步处理视觉和交互:
- 当
aria-invalid="true"时,用 CSS 选择器input[aria-invalid="true"]添加红边框、图标或背景色,让用户一眼识别异常字段 - 提交失败后,自动将焦点移到第一个校验失败的字段(
inputEl.focus()),屏幕阅读器会读出aria-invalid和aria-describedby关联的内容 - 错误容器本身不设
role="alert"——除非它是全局非关联提示;对于字段级错误,aria-describedby已足够,加alert可能重复播报 - 如果使用自定义下拉/日期组件等非原生控件,需额外确保其内部输入部分也正确透传
aria-invalid和aria-describedby
验证是否生效的小技巧
上线前快速检查:
- 用 VoiceOver(macOS/iOS)或 NVDA(Windows)打开表单,填写错误内容,看是否播报错误文案
- 检查 DOM 中 input 是否有
aria-invalid和aria-describedby,且describedby的 ID 对应真实元素 - 手动删除错误文案容器,观察屏幕阅读器是否静默(说明依赖关系成立)
- 用浏览器 DevTools 修改
aria-invalid值,确认视觉样式随之变化











