:focus 和 :valid 无法替代 javascript 表单验证,但可基于原生约束属性(如 required、type=”email”)提供轻量视觉反馈;:valid 仅在字段内容合法且存在校验属性时生效,无约束则永不匹配。

直接用 :focus 和 :valid 做表单验证,无法替代 JavaScript,但能快速提供视觉反馈——前提是表单字段有 required、type="email" 等原生约束属性。
为什么 :valid 不生效?检查 input 的约束属性
:valid 只在浏览器能执行原生校验时才触发,比如 input[type="email"] 输入非法邮箱、required 字段为空时会匹配 :invalid,反之才是 :valid。没有约束属性,:valid 永远不匹配。
- 必须加
required(哪怕只是占位)才能让空值触发:invalid -
type="email"、type="url"、minlength="2"等都会影响:valid/:invalid状态 -
pattern配合正则也能参与校验,例如pattern="[0-9]{6}"用于验证码
:focus + :valid 组合的常见误用
很多人写 input:focus:valid { border-color: green; },结果发现焦点下没反应——因为 :focus 是瞬时态,而 :valid 需内容合法,两者同时满足才有样式。用户刚点进去、还没输入时,字段为空 → :invalid → 样式不应用。
- 更实用的组合是
input:focus(强调当前操作项) +input:valid(独立反馈校验结果) - 避免写
input:focus:invalid来高亮错误——它只在「有焦点且内容非法」时生效,但用户可能已移开焦点,错误状态就消失了 - 若要持久提示错误,得靠 js 切换 class,或用
:user-invalid(chrome 102+ 支持,但兼容性差)
简洁验证样式的实操写法
用 border + transition 实现轻量反馈,不依赖 JS:
立即学习“前端免费学习笔记(深入)”;
input { border: 1px solid #ccc; transition: border-color 0.2s; } input:focus { outline: none; border-color: #007bff; } input:valid { border-color: #28a745; } input:invalid:not(:placeholder-shown) { border-color: #dc3545; }
-
:not(:placeholder-shown)排除 placeholder 占位时的误判(否则一聚焦就红边) - 所有状态都走
border-color,避免重排,性能好 - 移动端注意
outline: none后需确保可访问性,可加box-shadow替代
真正复杂的验证逻辑(如用户名是否被占用、两次密码一致)必须交由 JS 处理,:valid 只能覆盖浏览器原生能力范围内的校验。别指望它识别自定义规则。