:valid和:invalid不实时,仅在校验触发后更新;需配合input事件+checkvalidity()实现每键变色,且必须配置required/type/pattern等验证属性,自定义校验须调用setcustomvalidity()。

:valid 和 :invalid 本身不“实时”,它们只在浏览器完成一次原生校验后才更新状态;想做到每敲一个键就变色,必须配合 checkValidity() 主动触发。
为什么写了 :invalid 却没反应?
根本不是 CSS 写错了,而是 HTML 没配对验证属性:
-
<input type="text">永远:valid—— 它没有内置规则,加required也不够,必须搭配type="email"、pattern或minlength等至少一项约束 -
pattern值不能带前后斜杠:pattern="[0-9]{6}"✅,pattern="/[0-9]{6}/"❌ -
type="phone"这类自定义类型会被降级为text,直接失去所有校验能力 - 空的
required字段在页面加载完瞬间就是:invalid,这不是 bug,是规范行为
怎么让边框在输入过程中立刻变色?
靠监听 input 事件并调用 checkValidity(),而不是等失焦或提交:
- 用
input事件(不是change),因为后者只在 blur 后触发 - 代码只需一行:
el.addEventListener('input', () => el.checkValidity()) - 部分浏览器会自动节流,手动频繁调用
checkValidity()不会卡顿,也无报错 - 别给
:invalid加transition—— 错误反馈需要明确即时,加动画反而造成压迫感;可单独重置input:invalid { transition: none; }
如何避免一打开页面就全红?
初始红框来自空 required 字段被判定为无效,解决思路是延迟视觉反馈时机:
- 现代方案:
input:user-invalid—— 只在用户编辑过且当前值不满足约束时匹配,但 Safari 16.4+ 才完全支持 - 兼容方案:
input.touched:invalid,监听input或blur后加touched类 - 折中技巧:
input:not(:placeholder-shown):invalid,前提是设置了placeholder属性 - 绝对别用
:focus:invalid做唯一判断 —— 用户聚焦后删空,依然触发,体验断层
真正容易被忽略的是:自定义校验(比如用户名是否已存在)不会触发 :valid/:invalid,除非你显式调用 setCustomValidity("") 并确保每次校验都传入正确字符串 —— 漏掉一次,状态就卡死。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











