:invalid 一加载就标红空字段是规范行为而非 bug,因 required 字段初始为空即被判定非法;:invalid:not(:placeholder-shown) 是最轻量纯 css 解法,需配合非空 placeholder 使用,兼容性好。

为什么 :invalid 一加载就标红空字段
这不是 bug,是规范行为:required 字段初始为空时,浏览器直接判定为非法值,:invalid 立即匹配。你没输任何内容,边框已经变红,用户还没开始填,体验就崩了。
:invalid:not(:placeholder-shown) 是最轻量的纯 CSS 解法
它能确保「只在用户输入过、且输错了」才触发样式,不依赖 JS,兼容性好(Chrome 57+ / Firefox 52+ / Safari 15.4+)。
- 必须给
<input>加placeholder属性,否则:placeholder-shown永远不成立 - 写法示例:
input:invalid:not(:placeholder-shown) { border-color: #e53e3e; } - 注意:如果 placeholder 是空字符串
placeholder="",它仍算“已显示”,但不会视觉呈现——这会导致:not(:placeholder-shown)失效 - 移动端软键盘弹出后 placeholder 可能短暂消失,造成误触发;建议用非空占位符,如
placeholder=" "(带空格)更稳妥
用 .was-validated 类控制全局验证时机
当需要统一响应表单提交动作(比如点击「提交」后才高亮所有错误项),JS 主动加类是最可靠方案。
- HTML 中给
<form></form>加novalidate,禁用浏览器默认弹窗干扰 - 提交时调用
event.preventDefault(),再遍历所有input,对!el.checkValidity()的加.invalid类 - CSS 写成:
.was-validated input:invalid { border-color: #dc3545; },避免直接绑定:invalid - 别漏掉降级:加一条
input:invalid:not(.was-validated) { border-color: #ced4da; },让无 JS 环境仍有基础样式
:user-invalid 是未来方向,但别现在全靠它
它只在用户编辑过且值非法时触发,语义精准,但支持度有限(Chrome 102+ / Firefox 119+ / Safari 16.4+),2026 年仍不能作为唯一方案。
- 写法:
input:user-invalid { border-color: #d32f2f; } - 它不与
:valid对称——没有:user-valid,所以不能用它做成功反馈 - 旧版 Safari(
- 不要和
:focus混用,比如:focus:user-invalid在部分 Android 浏览器中行为不稳定
真正容易被忽略的是 placeholder 的存在感——它不是装饰,而是触发 :not(:placeholder-shown) 的开关;而 novalidate 也不是可选项,它是接管验证流程的前提。这两个看似次要的属性,恰恰卡住了整个纯 CSS 延迟反馈的命门。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











