required 属性仅对 text、email、number、tel、url、date、checkbox、radio、file、select 和 textarea 等具空值语义的 input 类型生效,hidden、button、image、range、color 等类型忽略该属性;表单提交时校验仅触发于 type="submit" 按钮点击或可编辑字段回车,form 缺失、按钮 type 非 submit、event.preventDefault() 后未调 checkValidity()、JS 直接调 submit()、字段 disabled 等均绕过校验;移动端旧版 iOS Safari 对 file/select 的 required 支持不稳定,需 JS 降级;默认提示不可定制,须用 setCustomValidity() 配合空字符串清空;:invalid 伪类初始即生效,可用 input:invalid:not(:placeholder-shown) 延迟反馈;框架中受控组件需初始化 value="" 避免首次渲染即校验失败;aria-required 仅语义标记,不触发校验;服务端必须二次校验,不可信任前端。

required 属性只对特定 input 类型生效
加了 required 却没拦住提交?先确认你用的 type 是浏览器真正校验的类型。它只在具备明确“空值语义”的控件上起作用:text、email、number、tel、url、date、checkbox、radio、file、select 和 textarea 可以;而 hidden、button、image、range、color 一律忽略——写了也白写。
特别注意:checkbox 加 required 表示必须勾选;radio 组里只要任意一个带 required,就表示该 name 下至少选一个;select 必须配一个 <option value="">请选择</option>,且不能加 selected,否则用户不动它也能绕过校验。
表单提交时 required 不触发的常见原因
不是属性加错,而是触发条件没满足。原生校验只响应两种动作:点击 type="submit" 按钮,或在可编辑字段中按回车。以下情况会完全跳过校验:
-
form标签缺失或被意外移除(required必须依附于语义化表单) - 用了
<button type="button"></button>或没写type(默认是button),不是submit - 在
submit事件里写了event.preventDefault(),但没手动调form.checkValidity() - 用 JS 直接执行
form.submit()—— 这个调用不触发任何原生校验逻辑 - 字段被设为
disabled(直接跳过校验),或readonly(仍参与校验)
移动端尤其要注意:旧版 iOS Safari(≤15.4)对 type="file" 和 type="select" 的 required 支持不稳定,建议加 JS 降级兜底。
立即学习“前端免费学习笔记(深入)”;
如何让 required 的提示更可控
浏览器默认提示文案无法通过 HTML 修改,也不能隐藏或定制样式。唯一合法干预方式是 JS 的 setCustomValidity(),但必须配对清空:
- 输入为空时调
el.setCustomValidity('用户名不能为空') - 输入非空时必须立刻调
el.setCustomValidity('')(传空字符串才能恢复原生逻辑) - 推荐监听
input事件而非blur,避免用户输一半就卡在校验失败状态 - 不要在
submit事件里才开始设 custom message——那时已晚,得提前同步 validity 状态
另外,:invalid 伪类一加载就生效,会导致页面刚打开所有必填框全变红。想“用户动过再反馈”,可用 input:invalid:not(:placeholder-shown) 配合 placeholder 控制初始样式。
React/Vue 中用 required 容易踩的坑
框架受控组件会让 required 行为变得反直觉:
- 如果
value={undefined}或value={null},DOM 实际值会被设为空字符串,required立刻判定为“缺失”,首次渲染就红框+聚焦 - 安全做法是初始化为
value="",或改用非受控模式(ref获取值) - 自定义封装组件(如 Ant Design 的
Input)若没透传required属性,该属性就等于没写 -
aria-required="true"仅作语义标记,不影响校验行为,不能替代required
真正最常被忽略的是:服务端永远要二次校验。前端删掉 required、禁用 JS、用 curl 提交,照样能发空数据过去。后端必须检查字段是否存在、是否为 null、是否为纯空格或空字符串——这些都算缺失。



















