直接用:invalid伪类可实现基础错误样式,但必须配合required/type等校验属性,并用:invalid:not(:placeholder-shown)规避页面加载时空字段误标红;它仅作用于原生表单控件,不触发于div等容器,且依赖浏览器内置验证逻辑而非内容为空即生效。

直接用 :invalid 伪类就能实现基础错误样式,但必须配合校验属性且避开空字段误触发——否则一打开页面所有必填项全变红,用户会懵。
为什么 :invalid 一加载就标红?
因为 required 字段初始为空,浏览器按规范判定为非法状态,:invalid 立即生效。这不是 bug,是 HTML5 验证的默认行为。
- 必须给
input加placeholder属性,否则:not(:placeholder-shown)条件永远不成立 - 推荐组合写法:
input:invalid:not(:placeholder-shown),只在“已输入但错误”时触发 - 旧版 Safari 对
:user-invalid支持更稳,但它仅在 Chrome 102+ / Firefox 119+ / Safari 16.4+ 可用,不能当默认方案 -
:invalid不作用于div或包装容器,只对input、select、textarea生效
怎么避免纯 CSS 方案失效?
浏览器对 :invalid 的重绘不敏感,尤其 Safari 容易跳过中间状态;display: none 和 transition 无法共存,动画会直接失效。
- 过渡必须用可插值属性:
opacity、transform、visibility - 正确写法示例:
input { opacity: 1; visibility: visible; transition: opacity .2s, transform .2s; } input:invalid:not(:focus) { opacity: 0; visibility: hidden; transform: scale(.95); } - 不要在 Less mixin 外层写
&:focus:invalid—— 编译后选择器丢失上下文,浏览器直接忽略 - 用属性选择器收束更可靠:
input[required]:invalid比.form-control:invalid权重明确、意图清晰
要不要用 JS 控制状态类?
要。主流框架(Ant Design、Bulma、Bootstrap)都用 is-invalid 或 has-error 这类显式状态类,因为可控、可预测、能区分错误类型。
- 监听
blur或submit后调用element.checkValidity(),再手动加error-shown类 - BEM 推荐写法:
form__field--email-format-invalid,而不是笼统的form__field--error -
:invalid适合做轻量边框反馈,JS 状态类负责业务级提示(如图标、文案、强度条) - 如果用了 Shadow DOM 或 CSS-in-JS,
:invalid可能被作用域隔离,需确认样式是否穿透到真实节点
真正关键的不是怎么写 CSS,而是 HTML 是否带 required、type="email"、pattern 这些约束属性,以及是否理解 :invalid 只反映浏览器内置校验结果——它不校验,只“报信”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











