required属性仅对表单控件标签(、、)生效,不作用于、等非控件标签;hidden类型忽略required;提交时触发校验,空值或空白字符视为未填写;需服务端二次校验。

required 属性加在哪个标签上才生效
只有表单控件标签(<input>、<select></select>、<textarea></textarea>)支持 required,它不会作用于 <div>、<code><label></label> 或包装容器。
常见错误是把 required 写在 <label></label> 上,或者以为加在父 <form></form> 就能批量控制——都不行。
-
<input type="text" required>✅ 有效 -
<input type="hidden" required>❌ 无效(浏览器忽略 hidden 类型的 required) -
<input type="checkbox" required>✅ 但语义是“必须勾选”,不是“必须填值” -
<select required><option value="">请选择</option></select>✅ 但需确保首项value为空字符串,否则选中即满足,失去校验意义
required 触发校验的时机和条件
浏览器原生校验只在提交时(form.submit() 或用户点 <button type="submit"></button>)触发,不监听输入变化、失焦或按键事件。
这意味着:用户输一半就切走,不会弹红框;用 JS 调用 form.submit() 会触发,但调用 element.click() 模拟点击 submit 按钮不一定触发(取决于是否真正触发 submit 事件)。
立即学习“前端免费学习笔记(深入)”;
- 空字符串、仅空白字符(
"\t\n ")都被视为未填写,触发校验失败 -
<input type="number">留空算未填写,但输入非数字(如 "abc")会触发类型校验,优先级高于 required - 如果同时设了
required和pattern,两者都必须满足,缺一不可
required 和 JavaScript 校验的关系
加了 required 不代表可以跳过 JS 校验。它的作用只是提供最基础的阻断+提示,且样式和提示文案不可控、不可本地化。
更关键的是:JS 可以绕过它——比如直接修改 input.value 后调用 form.reportValidity(),或用 event.preventDefault() 拦截 submit 后自行处理。这时候 required 仅作为 HTML 层面的声明存在,不参与逻辑。
- 不要依赖
input.checkValidity()的返回值做业务分支,除非你明确要复用浏览器校验逻辑 -
form.addEventListener("submit", e => { if (!e.target.checkValidity()) e.preventDefault(); })是常见但冗余的做法——required本身就会阻止提交,加这层只是为自定义提示 - 服务端永远要重新校验,
required完全不防绕过
移动端和旧浏览器的兼容性注意点
required 在 IE10+、Edge、Chrome、Firefox、Safari(含 iOS)均支持,但 Android 4.3 及更早 WebView 有 bug:对 <select></select> 的 required 不触发校验。
另一个实际坑是:iOS Safari 在 <input type="date"> 上,即使未选日期,也不总按 required 阻止提交——它可能把默认值(如 "1970-01-01")当作已填写。
- 涉及日期/时间控件时,建议额外用 JS 判断
input.value === "" - 若需支持低版本 WebView,可用
data-required自定义属性 + JS 补充校验,避免依赖原生行为 -
required的错误提示气泡位置在移动端常被键盘遮挡,无法调整,这是纯 UI 层限制











