:valid和:invalid伪类仅反映原生校验状态,不生成错误文案;需配合相邻兄弟选择器(如input:invalid:not(:placeholder-shown)+.hint)控制提示元素显隐,且提示元素必须紧跟对应input。

为什么 :valid 和 :invalid 不能直接显示错误文案
这两个伪类只反映原生表单验证的实时状态(比如 required、type="email"、pattern 是否通过),但它们本身不触发任何 DOM 变化,也不生成提示文本。常见错误是写成 input:invalid { color: red; } 就以为能弹出提示——其实用户根本看不到“为什么错”。必须配合 ::placeholder、label、span 或 JavaScript 才能真正提示。
如何用纯 CSS 控制提示元素显隐
核心思路:把提示文案放在表单控件后,用兄弟选择器 + 伪类联动控制 display 或 visibility。
- 提示元素必须紧跟在对应
input后(同级、相邻),才能用+选择器匹配 -
:invalid:not(:placeholder-shown)是关键组合:排除空输入时误判(否则 placeholder 还在就触发 invalid) - 对
type="email"等控件,即使值为空,只要 focus 后 blur,浏览器也会立即校验并设为:invalid
示例:
input:invalid:not(:placeholder-shown) + .hint {
display: block;
}
input:valid + .hint {
display: none;
}
.hint 是紧邻的 <span class="hint">请输入有效邮箱</span>。
立即学习“前端免费学习笔记(深入)”;
哪些表单属性会触发 :valid/:invalid
仅响应 HTML5 原生约束,不响应自定义 JS 校验结果:
-
required—— 空值即:invalid -
type="email"、type="url"、type="number"—— 格式不符即:invalid -
min/max(用于 number/date) -
pattern(正则匹配失败即:invalid) - 不响应
disabled或readonly的校验状态
注意:type="text" 即使加了 pattern,也必须配合 :invalid 才生效;单独 pattern 不会自动触发样式。
容易被忽略的兼容性与行为细节
:valid/:invalid 在 Safari 15.4+ 才支持 :placeholder-shown 组合,旧版 Safari 会误显提示;Chrome/Firefox 支持良好。
- 用户未输入时,
required字段默认是:valid(因为值为空但尚未校验),只有交互后(blur 或 submit)才更新状态 - 提交时浏览器会自动调用
checkValidity(),此时所有字段强制校验,:invalid生效 - 用 JS 调用
setCustomValidity('')可清除 invalid 状态,但不会影响 CSS 伪类——必须靠真实值变更或重新校验
真要稳定提示,还是得监听 input 和 blur 事件补一手 JS,CSS 只适合做视觉反馈层。


















