:required 是仅匹配支持且声明了 required 属性的原生表单控件的伪类选择器,不生效常见原因包括属性写法错误、元素类型被规范排除、框架未透传属性、优先级被覆盖或误用于替换元素。

:required 本身不标记任何东西,它只是个匹配器——你写了 input:required { border-color: red; },它才“标记”;不写,就什么都不会发生。
为什么写了 :required 样式却没生效
最常见原因不是语法错,而是匹配对象根本不存在或被忽略:
-
required是布尔属性,必须写成required或required="",写成require="true"或required="false"都无效 -
input type="hidden"、input type="button"、input type="submit"即使加了required,:required也完全不匹配(规范明确排除) - React/Vue 等框架封装的组件,若没把
required属性透传到底层<input>,CSS 就找不到目标 - 选择器优先级被覆盖:比如全局重置写了
input { border: 1px solid #ccc; },而你的input:required没加权重,样式就被压掉了
:required 能匹配哪些元素
只认三类原生表单控件,且仅当它们支持并实际声明了 required 属性:
-
<input type="text">、<input type="email">、<input type="checkbox">、<input type="radio">(注意:radio组需给至少一个加required才生效) -
<select required></select>(但要求有非空<option value=""></option>且未设selected,否则默认值可能绕过校验) <textarea required></textarea>-
<input type="date">、<input type="number">等也支持,但type="range"和type="color"不参与约束验证,:required不匹配
用 ::after 加星号必须绕开 <input>
<input> 是替换元素(replaced element),不能直接用 input:required::after 插入内容——浏览器会忽略它。正确做法是把星号挂在 <label></label> 上:
- 确保
<label></label>正确关联控件(用for属性或嵌套) - 推荐写法:
label:has(> input:required), label:has(> select:required), label:has(> textarea:required) { position: relative; }+label:has(> input:required)::after { content: " *"; color: #d32f2f; } - 兼容旧浏览器(如 Safari ≤15.4)时,改用 class 驱动:
label.required::after,并在 JS 或模板中同步控制class和required属性 - 别用
input:required + label::before—— DOM 顺序不固定,兄弟选择器极易失效
:required 和 :invalid 别混着乱用
页面一加载,空的必填字段就同时满足 :required 和 :invalid,这时候样式谁赢取决于声明顺序和权重:
- 想让“必填但未填”才变红,而不是一进来就红,用
input:required:not(:valid)更精准(:valid在空值时为false) - 避免写全局
:invalid { border-color: red; },否则非必填字段输错也会红,干扰用户判断 -
:placeholder-shown可辅助过滤:空输入框还显示 placeholder 时,:invalid:not(:placeholder-shown)才触发错误态,防止过早标红 - 记住:
:required是静态属性快照,:invalid是动态验证状态,两者生命周期不同步
真正容易被忽略的是:加红色边框对色觉障碍用户几乎无效,必须同步提供形状、文字或 ARIA 提示;而 :required 本身不解决可访问性问题,它只是样式起点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











