:in-range 和 :out-of-range 仅提供样式反馈,需 type="number" 且 min/max 同时存在合法值,value 必须为可解析数字,边界为闭区间,无法通过 JS 查询,应配合 :valid/:invalid 使用。

:in-range 和 :out-of-range 不是“限制输入”的手段,它们只负责样式反馈——值在 min/max 闭区间内时匹配 :in-range,超出时匹配 :out-of-range;空值、非法字符(如 "abc")则两个都不匹配。
必须同时满足这四个条件,:in-range 才会生效
很多样式写完没反应,不是选择器错了,而是浏览器压根没启动范围判定:
-
type必须是"number"("date"、"time"也行,但type="text"加min/max完全无效) -
min和max属性必须**同时存在**,且值为合法数字字符串(如min="0",不能是min=""或min="auto") - 用户必须输入了可被解析为数字的值(
"10"、"-5.5"可以,"10px"、" "、"null"不行) - JS 直接赋值
input.value = "200"不会触发伪类更新;需手动派发事件:input.dispatchEvent(new Event('input', { bubbles: true }))
:in-range 和 :out-of-range 的边界怎么算?
它们只做一件事:判断当前 value 是否落在 [min, max] 闭区间内。和 step、格式校验、required 都无关:
-
value="10"+min="10" max="20"→ 匹配:in-range(端点包含) -
value="20"+ 同上 → 仍匹配:in-range -
value="10.5"+step="1"→ 仍匹配:in-range(step不影响范围判定,只影响:valid) -
value="abc"或value=""→ 两个伪类都不匹配(此时应靠:invalid捕获)
仅靠伪类不够,得组合 :valid 和 :invalid
:in-range 对空值“默认放行”,:out-of-range 对非法输入“视而不见”——这会导致视觉反馈断层。真正可用的组合是:
立即学习“前端免费学习笔记(深入)”;
-
input:valid:not(:placeholder-shown)→ 值合法且非占位符状态(推荐用作“正常态”) -
input:invalid:not(:placeholder-shown)→ 涵盖空值、超限、非法格式三类问题(比:out-of-range更全面) - 务必加
:not(:placeholder-shown),否则用户还没输就标红 - 避免用
display: none隐藏提示文案,会破坏屏幕阅读器可访问性
容易被忽略的关键事实
:in-range 状态无法通过 JS 查询——getComputedStyle(input).content 读不到,element.matches(':in-range') 在多数浏览器中返回 false 即使样式已生效;它纯粹是渲染层的匹配信号,不暴露给 DOM API。如果你需要程序化判断范围,必须自己解析 min/max 并对比 input.valueAsNumber。


















