aria-invalid="true"需配合aria-errormessage或aria-describedby及role="alert"才能触发屏幕阅读器播报错误文案,单独使用无效;错误文案须可见、自然语言、动态同步状态,且id唯一。

aria-invalid="true" 本身不触发语音播报,必须配合其他属性
单纯设置 aria-invalid="true" 只是标记状态,屏幕阅读器(如 NVDA、VoiceOver)不会主动读出“错误”二字。它需要和 aria-describedby 或 aria-errormessage 配合,把错误文案的 ID 关联过去,才能让视障用户听到具体提示。
常见错误是只加 aria-invalid,却不提供可读的错误文本,导致用户知道“这个框有问题”,但不知道“哪里错了、怎么改”。
-
aria-invalid的值推荐用"true"(布尔值字符串),不用"grammar"或"spelling"—— 这些语义在主流阅读器中基本不被识别 - 错误文案必须是可见的 DOM 元素(哪怕视觉上用 CSS 隐藏),且不能用
display: none或visibility: hidden,否则会被阅读器跳过 - 推荐用
aria-errormessage(HTML5 新增),比aria-describedby语义更明确,部分阅读器会优先播报它
正确绑定错误文案的两种写法
以下两种方式都有效,但行为略有差异:
<input type="email" aria-invalid="true" aria-errormessage="email-error"><div id="email-error" role="alert">请输入有效的邮箱地址</div>
或
<input type="email" aria-invalid="true" aria-describedby="email-error"><div id="email-error" role="alert">请输入有效的邮箱地址</div>
role="alert" 很关键:它让阅读器以中断式语音播报该内容(类似弹窗提示),避免被忽略。没有它,即使关联了 ID,也可能只作为普通描述被轻声带过。
- 如果错误文案动态显示/隐藏,务必同步更新
aria-invalid值("true"↔"false"),否则状态滞后 -
aria-errormessage和aria-describedby不能同时用在同一元素上——阅读器行为未标准化,可能冲突 - 不要把错误文案放在
<label></label>里再用aria-labelledby,label 是用于说明用途的,不是报错场景
为什么不能只靠 CSS 视觉反馈?
很多团队加红框、变色、显示 ❌ 图标就认为“提示完成了”,但这对屏幕阅读器用户完全无效。他们既看不到颜色变化,也听不到图标含义。
- 视觉错误样式(如
border-color: #d32f2f)必须搭配可访问的 ARIA 状态,二者缺一不可 - 错误文案要写自然语言,避免“校验失败”“字段非法”这类开发术语,用“手机号格式不对,请输入11位数字”这种用户能懂的话
- 如果错误文案是异步返回(如后端验证),要等文案渲染完成后再设置
aria-invalid="true",否则阅读器可能读到空内容
测试时最容易漏掉的三个点
本地用 VoiceOver(macOS)或 NVDA(Windows)测一遍,重点看这三处是否连贯:
- 焦点进入输入框时,是否只读 label(正常);焦点离开且出错后,是否紧接着读出错误文案(必须)
- 用户修改内容并再次失焦,错误文案消失时,
aria-invalid是否及时设为"false",否则阅读器仍会尝试读不存在的aria-errormessage - 表单提交失败后批量标红多个字段,每个
input的aria-errormessageID 是否唯一,重复 ID 会导致阅读器读错内容
最麻烦的是动态表单——比如添加多组联系人,每组都有邮箱字段,错误 ID 必须用唯一标识生成(如 email-error-2),硬编码 ID 会串场。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











