:required 伪类仅匹配明确带有 required 属性的合法表单元素(如 input[type!="hidden"]、select、textarea),不生效通常因缺少该属性或元素不支持;它反映结构要求,而非实时校验状态,应配合 :valid/:invalid 使用。

为什么 :required 有时不生效
直接写 input:required { border: 2px solid red; } 却没反应?大概率是浏览器默认样式覆盖了你的规则,或者元素根本没带上 required 属性。CSS 伪类 :required 不会自动识别“逻辑上该填”的字段——它只匹配明确写了 required 属性的表单控件(如 <input required>、<select required>、<textarea required>)。没有这个 HTML 属性,CSS 就无从匹配。
常见误操作包括:
• 在 JS 动态添加 required 但忘了触发重绘(其实不用管,DOM 更新后自动生效)
• 用了 required="false" —— 这个写法无效,布尔属性只要存在就为真,删掉才是取消
• 对 <input type="hidden"> 或 <button> 用 :required —— 它们不支持该属性,不会被选中
:required 能用在哪些元素上
不是所有表单元素都支持 required 属性,因此 :required 也只能作用于合法目标:
-
<input>(除type="hidden"、"button"、"image"、"reset"、"submit"外) -
<select>(必须有required,且第一个<option>不能有selected,否则可能绕过校验) <textarea>
例如:<input type="email" required> ✅ 可被 input:required 匹配<input type="checkbox" required> ✅(用户必须勾选)<input type="radio" name="x" required> ✅(同 name 的任一 radio 被选即满足)<input type="file" required> ✅(至少选一个文件)
立即学习“前端免费学习笔记(深入)”;
和 :invalid 搭配时要注意什么
:required 只表示“必须填”,不表示“当前是否已填”。真正反映校验状态的是 :invalid(含空值或格式错误),两者常一起用,但行为不同:
-
input:required:只要写了required,无论有没有值、有没有焦点,始终匹配 -
input:invalid:required:仅当字段为空(或格式错)且带required时才匹配 -
input:valid:required:已填且通过基础校验(如 email 格式对)时匹配
典型用法是区分“未填”和“填错”:input:required:not(:valid) { background: #fee; } // 未填或填错input:required:valid { background: #efe; } // 已填且合规
注意::invalid 在用户首次交互前可能不触发(部分浏览器延迟校验),如需立即高亮,可加 input:required { background: #f9f9f9; } 作基础提示
兼容性和真实渲染限制
:required 自 Chrome 10、Firefox 4、Safari 5.1 起就支持,IE 不支持(IE11 及以下直接忽略该选择器)。但更大的坑在于视觉反馈:
- 某些浏览器(如旧版 Safari)对
select:required的:invalid状态响应滞后,需用户失焦才更新 -
input[type="number"]空值时可能被当成0,导致:invalid不触发 —— 建议配合min/step或用 JS 补充判断 - 自定义组件(如封装的
<MyInput>)若没透传required到底层<input>,:required选不到它
最稳妥的做法:把 :required 当作“结构标记”用(比如加星号 ::after),把校验逻辑和视觉反馈交给 :valid/:invalid 或 JS 控制 —— 毕竟用户关心的是“我现在填得对不对”,而不是“这个框理论上要不要填”。


















