仅靠 required 属性无法向屏幕阅读器用户传达“必填”语义,必须配合显式文本提示(如 label 中写“(必填)”)或正确使用的 ARIA 属性(如 aria-label 包含字段名与“必填”,或 aria-labelledby 关联冗余提示),同时确保视觉标识(如星号)辅以 aria-hidden 和 visually-hidden 文本,并在错误状态同步设置 aria-invalid="true"。

仅靠 required 属性无法向屏幕阅读器用户传达“必填”语义,必须配合显式文本提示或 ARIA 属性。
label 里没写“必填”,required 就是摆设
浏览器原生 required 只触发提交校验,不改变 label 文本、不播报“必填”、不提供视觉提示——屏幕阅读器读到的仍是“邮箱”,不是“邮箱(必填)”。用户根本不知道该字段不能留空。
- 最稳妥做法:在
label文本末尾加括号说明,如<label for="email">邮箱(必填)</label> - 若设计不允许修改文案,可用
aria-label补充,但必须包含原始字段名,例如aria-label="邮箱,必填";单独用aria-label="必填"会覆盖原名,导致读屏只说“必填”,用户不知道是哪个字段 - 禁用
title或placeholder替代 label 提示:它们不被所有读屏软件稳定读出,且无法触发点击聚焦
aria-required="true" 要配对使用,不能单飞
aria-required="true" 本身能被读屏识别,但它只是状态标记,不自带文本解释。如果 label 没提“必填”,光加这个属性,NVDA 或 VoiceOver 通常只报“编辑框”,不提“必填”二字。
- 必须和 label 文本协同:要么 label 写明,要么用
aria-labelledby把额外提示元素(如带“*”的 span)绑定过去 - 示例:
<label id="email-label" for="email">邮箱</label><span aria-hidden="true">*</span><input aria-labelledby="email-label" aria-required="true" id="email"> - 注意:
aria-required对type="checkbox"和type="radio"组合无效——这类控件应靠逻辑分组与 JS 校验控制必填
视觉“必填标识”必须对齐无障碍需求
星号(*)、红色边框、图标等纯视觉提示,对屏幕阅读器用户完全不可见。若只靠 CSS 实现,等于没提示。
立即学习“前端免费学习笔记(深入)”;
- 星号必须用
aria-hidden="true"包裹,避免读屏重复播报;同时用visually-hidden类(非display: none)提供冗余文本,如<span class="visually-hidden">,必填</span> - 错误状态下的红框样式(
:invalid或.error)需同步设置aria-invalid="true",否则读屏仍认为字段“正常” - 禁用
::after伪元素生成星号:它不在 DOM 中,无法被辅助技术访问
真正落地时,最容易被忽略的是 label 文本与 ARIA 的协同节奏——不是“加了 required 就完了”,而是每次 label 渲染、每次动态插入字段、每次国际化切换,都得重新确认“必填”语义是否完整抵达读屏用户耳中。



















