:required 和 :optional 伪类仅依据 html 中 required 属性是否存在来匹配,不认值、js 设置或 disabled 状态;仅原生支持 required 的元素(如非 hidden type 的 input、textarea、select)有效;required="false" 仍匹配 :required;需用 input:not(:disabled):optional 等组合避免误判;样式建议结合边框、颜色、焦点反馈与标签提示;兼容现代浏览器,旧版需 js 通过 hasattribute('required') 动态加类降级。

直接用 :required 和 :optional 伪类就能区分,但关键在写法要准、逻辑要清——它们只看 HTML 中 required 属性存不存在,不认值、不认 JS 设置、也不管字段是否禁用。
哪些元素能被匹配
只有原生支持 required 属性的表单控件才有效:
-
<input>(type不是hidden、image、submit、button等) <textarea></textarea><select></select>
checkbox 和 radio 默认属于 :optional;input[type="hidden"] 完全不参与匹配;<button></button>、<output></output> 或自定义组件无效。
为什么 :optional 没生效?常见坑点
最常出错的是误以为 required="false" 能让字段“变可选”——其实只要写了 required(哪怕空着、写成 required=""),它就匹配 :required,完全跳过 :optional。
-
<input name="email">→ 匹配:optional -
<input name="phone" required>或<input name="phone" required="anything">→ 只匹配:required -
<input disabled>没写required→ 仍匹配:optional(易误导用户,需手动排除)
安全写法是加限制:input:not(:disabled):optional 或 input:not(:readonly):optional。
样式设置建议
避免仅靠颜色区分(影响可访问性),推荐组合视觉线索:
- 必填项用实线+强调色边框:
input:required { border: 2px solid #e53935; } - 选填项弱化处理:
input:not(:disabled):optional { border: 1px dashed #ccc; color: #666; } - 聚焦时增强反馈:
input:required:focus { box-shadow: 0 0 4px rgba(229, 57, 53, 0.4); } - 标签后加文字提示:
label > input:required + span::after { content: "(必填)"; color: #e53935; }
注意两个伪类选择器权重要一致,比如都用 input:required 和 input:optional,别一个加 ID 或嵌套多层,否则容易覆盖失效。
兼容性与降级方案
Chrome 10+、Firefox 4+、Safari 15.4+、Edge 79+ 均原生支持。旧版 Safari 或 IE 不识别,会直接忽略规则,无报错。
需要兜底时,可用 JS 扫描并加 class:
document.querySelectorAll('input, textarea, select').forEach(el => {
el.classList.toggle('is-optional', !el.hasAttribute('required'));
});
切记用 hasAttribute('required') 判断,不要用 el.required(后者受 disabled 影响,不可靠)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











