:required仅匹配显式声明required属性的表单控件,:optional匹配无required属性且支持原生验证的控件;二者均不依赖实际校验状态,仅由HTML属性决定,且不受formnovalidate影响。

伪类 :required 只匹配带 required 属性的表单控件
浏览器会严格依据元素是否显式声明了 required 属性来触发该伪类,和实际校验逻辑无关。哪怕你用 JavaScript 动态移除了 required 属性,样式也会立即失效。
-
→ 匹配:required -
→ 不匹配:required,哪怕后端强制要求它 -
→ 匹配;但若第一个有selected且为空值,仍算“未填”,:required样式照常生效 - 对
、、同样适用,但注意:单个radio组里只要有一个带required,整组都受约束(不过伪类只作用于那个带属性的元素)
伪类 :optional 是 :required 的补集,但不包含无验证能力的元素
它匹配所有**没有** required 属性、且本身支持原生表单验证的控件。关键点在于“支持验证”——、、 这类不参与提交校验的元素,即使没写 required,也不会被 :optional 选中。
-
→ 匹配:optional -
→ 也匹配:optional(有验证规则但没标必填) -
→ 不匹配:optional,因为不是可提交的表单控件→ 不匹配,type="hidden"被排除在验证流程外,CSS 伪类也不识别它别指望它们反映实时填写状态
:required和:optional都是静态属性匹配,和用户是否已输入、输入是否合法完全无关。想高亮“空但必填”的字段,得组合使用:required:invalid;想区分“已填”和“未填”,得靠:placeholder-shown或 JS 监听input事件加 class。-
input:required { border-left: 3px solid #007bff; }→ 所有必填项统一标识 -
input:required:invalid:not(:placeholder-shown) { background: #fff5f5; }→ 提交后空必填项才变红底(注意:invalid在未交互前可能不触发) -
input:optional:focus { opacity: 0.9; }→ 可选字段获得焦点时轻微降透明度,避免和必填项视觉权重混淆
兼容性与常见误用
这两个伪类在现代浏览器中支持良好(Chrome 10+、Firefox 4+、Safari 5.1+、Edge 12+),但 IE 完全不支持。如果你必须兼容 IE,只能用 JS 模拟或退回到 class 控制。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
input[required]:optional—— 逻辑矛盾,永远不匹配 - 错误写法:
input:required + label尝试给相邻 label 加样式 —— 大多数情况下 label 不在 input 后面,且+是紧邻兄弟选择器,容错极低 - 更可靠的做法:把
required属性同时作为 class 来用,比如,再写.required + label,这样可控性强,也方便 JS 操作
input:required { border-color: #dc3545; } input:optional { border-color: #6c757d; } input:required:focus, input:optional:focus { outline: none; box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25); }真正容易被忽略的是:当表单用了formnovalidate或novalidate属性时,:invalid和:valid会失效,但:required和:optional不受影响——它们只看属性存在与否,不依赖验证引擎是否开启。










