required属性仅对原生表单控件(如input、select、textarea)生效,对div/span或自定义组件无效;校验仅在submit事件或checkvalidity()调用时触发,不监听blur/input;提示文案和样式受限,需css配合:invalid或:user-invalid控制。

required 属性只作用于可提交的表单控件,不是所有元素都支持
直接给 <div> 或 <code><span></span> 加 required 没效果——它只对原生表单控件生效,比如 <input>、<select></select>、<textarea></textarea>。浏览器会自动忽略非表单控件上的该属性,控制台也不会报错,容易误以为“写了就管用”。
常见踩坑:给自定义组件(如封装的 <my-input></my-input>)加 required,但内部没透传到真实 <input> 上,导致校验失效。
-
required对<input type="hidden">、<input type="button">、<input type="reset">无效 -
<input type="file">支持required,但需注意:空文件选择框算“未填写”,点击提交时会触发提示 -
<input type="checkbox">和<input type="radio">的required行为不同:前者要求勾选,后者要求至少一个同name的选项被选中
浏览器原生校验触发时机很明确:仅在 submit 事件或 checkValidity() 调用时
页面加载后,即使字段为空,required 不会立刻标红或弹提示——它不监听 blur 或 input,纯粹是提交拦截机制。这点和 JS 校验逻辑完全不同,容易让人误以为“没生效”。
这意味着:用户可以自由输入、删除、留空,直到点提交按钮(或调用 form.submit())才触发校验。若想实现“失焦校验”,必须加 JS,已超出零脚本范畴。
- 点击
<button type="submit"></button>或回车提交表单时,校验立即触发 - 调用
form.checkValidity()或input.reportValidity()也会手动触发(但仍属 JS) - 使用
form.requestSubmit()同样触发原生校验,且不会绕过required
错误提示文案不可定制,且样式受限于浏览器 UA stylesheet
Chrome 显示 “Please fill in this field”,Firefox 是 “This field is required”,Safari 更简略。这些文案无法用 HTML 或 CSS 修改,title 属性也不影响校验提示内容。
视觉反馈方面,出错时浏览器会给元素加 :invalid 伪类,但默认无样式变化(除了某些浏览器对 input:invalid 加红色边框)。想统一高亮,得写 CSS:
input:invalid {
border-color: #e53e3e;
}
input:invalid:focus {
box-shadow: 0 0 0 1px #e53e3e;
}
注意::invalid 在初始加载时就可能匹配(比如空的 required 输入框),导致一进页面就红边。可用 :user-invalid(Chrome 102+、Firefox 119+)更精准控制——只在用户交互后或提交失败后生效。
required 和其他约束属性组合使用时,优先级和逻辑要理清
required 和 minlength、pattern、min/max 共存时,校验是“与”关系:全部满足才算有效。但触发顺序和错误提示由浏览器决定,通常只显示第一个不满足的规则对应的信息。
- 空值时,
required优先于pattern生效;填了内容才检查正则 -
<input type="email" required>:空 → 报 required;非邮箱格式 → 报 email 格式错误 -
<input pattern="[0-9]{3}" required>:空 → required 提示;填 "12" → pattern 提示;填 "1234" → 仍算通过(pattern 默认是“匹配即可”,非“精确匹配”),需加^$锚定
真正零脚本的预校验,就只是靠浏览器在提交那一刻拦住非法状态。别指望它代替 JS 做实时反馈或复杂逻辑——那是它的设计边界。











