:in-range和:out-of-range仅对type="number"、"range"、"date"、"datetime-local"、"month"、"week"且含有效min/max属性的input及progress元素生效;text、select、textarea等不支持。

:in-range 和 :out-of-range 只对设置了 min/max 属性的数字类表单元素生效,不是所有 input 都能用。
哪些元素支持 :in-range 和 :out-of-range
仅限带数值范围约束的原生控件:
-
input[type="number"](必须有min或max) -
input[type="range"](始终受min/max约束,默认 0–100) -
input[type="date"]、input[type="datetime-local"]、input[type="month"]、input[type="week"](需设min/max) -
progress元素(根据value与max关系判断)
input[type="text"]、select、textarea 即使加了 pattern 或 JS 校验,也**不触发**这两个伪类——它们只看 HTML 原生范围属性,不看正则或运行时逻辑。
:out-of-range 的样式写法和常见误用
直接写 input:out-of-range { border-color: red; } 是最常用方式,但要注意三点:
立即学习“前端免费学习笔记(深入)”;
- 样式只作用于该元素自身,无法通过
input:out-of-range + label影响兄弟标签(label 不是紧邻后续兄弟时更不可靠) - 如果元素初始值为空(
value=""),且未设置required,多数浏览器视为“未校验”,不会进入:out-of-range状态 -
input[type="range"]的:out-of-range实际极少触发——因为拖动滑块本身就被限制在min/max内;只有通过 JS 强行赋值超出范围时才生效
推荐组合写法,增强视觉反馈:
input:out-of-range {
border-color: #c00;
background-color: #ffebee;
box-shadow: 0 0 6px rgba(204, 0, 0, 0.2);
}
为什么不能只靠 :in-range/:out-of-range 做表单校验
这两个伪类纯属 CSS UI 状态标记,完全不阻断表单提交,也不影响 JS 的 checkValidity() 结果:
- 用户点击提交时,
:out-of-range元素仍可能通过(除非同时加了required或min/max且浏览器原生校验开启) - 移动端 Safari 对
:out-of-range的渲染延迟明显,有时输入后需失焦才更新样式 - 服务端和 JS 层仍必须独立验证——比如后端不能信任前端传来的
number值,JS 也应调用element.validity.rangeUnderflow或rangeOverflow判断
真正安全的做法是:用 :out-of-range 提供即时视觉提示,但提交前用 form.checkValidity() + 显式错误消息兜底。
容易被忽略的一点::in-range 在 input[type="number"] 中默认不显式生效——因为没超限就是常态,你得主动写 input:in-range { border-color: #4caf50; } 才能看到效果,而不是指望它“自动变绿”。


















