为什么我的表单错误提示对屏幕阅读器不可见?
大家好,我在做一个表单验证时遇到了无障碍问题。给输入框加了aria-describedby关联错误提示,但用NVDA读的时候完全没反应,这是为什么呢?
我按文档这样写的代码:
<label for="username">用户名</label>
<input type="text" id="username" aria-describedby="error-msg">
<div id="error-msg" role="alert">用户名不能为空</div>
检查过id拼写没问题,也试过把role改成status,还是不行。是不是还需要加其他属性?或者屏幕阅读器需要特定触发条件?
aria-describedby关联一个role="alert"的错误提示,确实不能保证屏幕阅读器会正确读出错误信息**。原因有几个:
1.
aria-describedby是描述性文本,屏幕阅读器在输入框获得焦点时不会主动读出它关联的内容,除非该内容有live region特性;2. 即使加了
role="alert",它也不是实时区域(live region),只有当它内容变化时才会触发读屏,但你的页面加载完错误提示就存在了,没有动态变化,所以没触发;3. 不同的屏幕阅读器行为差异很大,NVDA 对这种静态错误提示的兼容性本来就不太好。
要解决这个问题,建议的做法是:
- 把错误提示容器加上
role="alert"的同时,再加一个aria-live="assertive";- 并且确保错误提示是动态插入或内容变化的,这样 NVDA 等阅读器才会主动读出来;
- 同时保留
aria-describedby用于辅助描述(但不能只靠它)。你可以改成这样:
另外,如果你是在 JavaScript 中动态显示错误信息的,那建议在显示错误时,通过 JS 动态修改
顺便一提,MDN 的 ARIA 文档和 WAI-ARIA spec 都提到过类似问题,有兴趣可以看看 [MDN ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) 和 [WAI-ARIA Live Regions](https://www.w3.org/TR/wai-aria-1.1/#live_regions) 的说明。
总之,关键点就是:**错误提示需要配合
aria-live才能被 NVDA 正确识别并朗读**。aria-describedby的用法上。这个属性主要是用来提供额外描述信息的,但屏幕阅读器不会主动把关联的内容当作“即时更新”的提示来读出来。特别是你加了role="alert"或role="status",这种情况下aria-describedby就更不起作用了。可以优化成以下写法:
这里用了
aria-errormessage来代替aria-describedby,同时加上aria-invalid="true"表示当前输入有错误。这样屏幕阅读器就能正确识别并朗读错误提示了。另外提醒一下,确保错误提示内容是动态插入的(比如通过 JavaScript),而不是一开始就存在页面里,否则屏幕阅读器可能还是不会及时读出来。如果还遇到问题,记得检查下错误消息是否正确插入到了 DOM 中。