:invalid伪类可自动高亮未通过校验的表单控件,但仅在失焦或提交后稳定触发;需配合required等校验属性,建议结合:placeholder-shown区分空值与错误值,并用内联SVG图标增强可访问性。

用 :invalid 伪类自动高亮未通过校验的表单控件
浏览器原生支持 :invalid,只要元素有 required、type="email" 等校验属性,且当前值不满足规则,就会自动匹配该伪类。不需要 JS 监听或手动加 class。
注意:它只对「已失去焦点」或「提交过一次」的字段稳定触发——这是浏览器的懒校验策略,避免用户还没输完就标红。
-
:invalid在输入过程中可能不立即生效(比如邮箱字段输到一半a@,不会立刻标红) - 配合
:user-invalid(Chrome 102+、Firefox 119+)可实现更及时反馈,但兼容性需权衡 - 对
和同样有效,只要它们有required
样式建议:边框 + 背景 + 图标,别只靠颜色
纯红色边框对色觉障碍用户不友好,建议组合视觉线索。同时避免覆盖用户已输入的有效内容(比如不要把 background-color 设为深红遮住文字)。
input:invalid,
select:invalid,
textarea:invalid {
border-color: #d32f2f;
background-color: #fff8f8;
padding-right: 28px;
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 16px;
}
input:invalid {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23d32f2f'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
- 用内联 SVG 避免额外请求,图标直接嵌入
background-image - 保留
padding-right给图标留空间,防止文字被遮挡 - 慎用
outline: none—— 移除焦点轮廓会损害可访问性
如何让 :invalid 在输入时就响应?
原生 :invalid 不会在输入中实时更新,但可以靠 oninput + checkValidity() 手动触发重绘,或改用 :user-invalid。
立即学习“前端免费学习笔记(深入)”;
推荐轻量方案:监听 input 事件,给无效字段临时加一个 class(如 force-invalid),再用 CSS 覆盖:
input.force-invalid {
border-color: #d32f2f;
background-color: #fff8f8;
}
// JS
document.querySelectorAll('input[required], input[type="email"], input[type="url"]').forEach(el => {
el.addEventListener('input', () => {
el.classList.toggle('force-invalid', !el.checkValidity());
});
});
- 仅对明确需要实时反馈的字段启用,避免全局监听影响性能
-
checkValidity()返回false时才加 class,比单纯看value更准确(比如type="number"输入字母时也应标红) - 不要在
blur或submit里移除这个 class——用户仍需看到错误状态直到修正
和 :valid、:placeholder-shown 搭配使用更自然
单独用 :invalid 容易造成“空字段一打开就红”,体验生硬。结合 :placeholder-shown 可区分「未填」和「填了但错」:
input:not(:placeholder-shown):invalid {
border-color: #d32f2f;
}
input:valid {
border-color: #2e7d32;
}
input:placeholder-shown {
border-color: #bdbdbd;
}
-
:placeholder-shown表示 placeholder 还可见(即用户尚未输入),此时不应用:invalid样式 -
:valid可用于正向反馈(比如绿色边框),但注意:空字符串对required字段永远不匹配:valid - 所有这些伪类都依赖 HTML 层的校验属性(
required、minlength、pattern等),没写就不起作用
真正容易被忽略的是:校验逻辑必须前后端一致。CSS 的 :invalid 只是前端提示,后端仍要重新验证,否则用户禁用 JS 或绕过表单就能提交非法数据。










