required 和 aria-required="true" 必须同时存在才完整:前者触发浏览器原生校验与提交拦截,后者确保屏幕阅读器明确播报“必填”,二者分工明确、缺一不可。

单独写 aria-required="true" 不会阻止表单提交,也不会触发浏览器校验——它只对屏幕阅读器“说话”,别的都不管。
required 和 aria-required 必须同时存在才完整
浏览器原生校验靠 required,辅助技术感知靠 aria-required="true",两者分工明确,缺一不可。只写一个,等于只完成一半。
-
required触发提交拦截、影响移动端键盘类型(比如type="email"自动唤出 @ 键),但老版 JAWS 或 NVDA 在 IE/旧 Safari 下可能不播报“必填” -
aria-required="true"能让读屏软件明确朗读“必填”,但它对浏览器验证逻辑完全无感,空着照样能点提交 - 冗余写法:
<input required aria-required="true">—— 现代读屏基本能识别required,加aria-required是为兼容兜底,不是错误,但也不是必须 - 绝对不能写
aria-required="false"同时又带required,逻辑冲突会让部分读屏报错或跳过整个字段
:required 伪类只能匹配 input,label 上加了没用
很多人以为给 <label for="name">姓名</label> 加个 required 属性,再写 label:required::after 就能出星号——其实根本不会生效,因为 :required 只作用于原生表单控件元素。
- 正确做法是:把星号加在
label内部文本里,比如<label>姓名*</label>,或者用label:has(input:required)::after(Chrome/Firefox 支持,Safari 15.4+ 才行) - 如果 label 是
for关联方式,label:required永远选不到——required在input上,不在label上 - 伪元素
::after加的星号对屏幕阅读器不可读,仅作视觉提示;真要兼顾可访问性,得确保星号是 DOM 文本节点,或至少用aria-label补充说明 - 高对比度模式下,别依赖颜色区分必填,星号必须有足够对比度且位置稳定(中文习惯后置,RTL 语言需前置)
自定义组件里 aria-required 容易漏传
React/Vue 封装的 MyInput 组件,required 属性默认不会自动落到内部 input 上,aria-required 更常被彻底忽略——尤其是组件用了 div 包裹、或改用 role="textbox" 的情况。
立即学习“前端免费学习笔记(深入)”;
- 检查方法很简单:打开 DevTools → Elements 面板 → 找到最终渲染的
input标签 → 确认是否同时存在required和aria-required="true" - 常见漏传场景:组件接收
requiredprop,但只把它赋给外层容器;或动态控制必填状态时,只改了 JS 变量,没同步调用input.setAttribute('aria-required', 'true') - 用
role="textbox"模拟输入框时,aria-required="true"是必需的,因为原生required对非原生元素无效 - Ant Design、Element Plus 等 UI 库的文档里,要查 “支持原生属性透传” 或 “props spread” 相关说明,否则
required很可能只是摆设
aria-invalid 和 aria-describedby 必须配合使用
只标 aria-required="true" 不代表用户提交失败后你能“告诉”屏幕阅读器出错了——那需要手动设置 aria-invalid="true" 并关联错误消息。
- 错误消息元素必须有
id,比如<div id="email-error">邮箱不能为空</div> -
input必须通过aria-describedby="email-error"显式关联,否则读屏不会朗读该错误 -
aria-invalid值必须随状态实时更新:空值时设"true",填入后立刻设回"false",不能只靠 CSS 显示/隐藏错误文案 - 别用
placeholder="邮箱(必填)"替代真实校验逻辑——placeholder 不被所有读屏朗读,且输入后就消失,无法持续传达规则
最常被忽略的一点:服务端必须二次校验。前端 required 和 aria-required 全部失效时(比如禁用 JS、curl 提交、绕过前端逻辑),后端仍要判断字段是否为空字符串、null 或纯空白符。这不是“以防万一”,而是必做项。


















