:in-range 和 :out-of-range 需手动写CSS且仅在type为number/date/time/range、min/max合法存在时生效;值无法解析或缺属性则伪类不匹配,调试需用DevTools修改value验证状态。

:in-range 和 :out-of-range 不会自动高亮,必须手动写 CSS 样式,且只在极少数严格条件下生效——漏掉 min/max、type 错误或值非法,就完全不触发。
为什么写了 :out-of-range 样式却没反应
几乎全是这三个原因导致伪类根本没匹配上:
-
input没写min或max属性(哪怕只写一个,比如min="0",也比都不写强) -
type不是"number"、"date"、"time"或"range";type="text"加了min="0"也彻底无效 -
min或max值非法:比如min=""、min="ten"、min="10px"—— 浏览器解析失败,伪类直接跳过
调试时别靠猜:打开 DevTools,在 Elements 面板里直接改 value 为超界值(如 value="200"),看元素是否被标记为 :out-of-range 状态。
:in-range 和 :out-of-range 的真实匹配逻辑
它们只做一件事:判断当前 value 字符串能否被解析为合法数值/日期,并是否落在 [min, max] 闭区间内。不是“有效”,只是“在范围内”:
立即学习“前端免费学习笔记(深入)”;
-
value="10"+min="10" max="20"→ 匹配:in-range(端点包含) -
value="abc"或value=""→ 两个伪类都不匹配(既不是 in,也不是 out) -
type="range"几乎永远匹配:in-range,因为浏览器强制截断 value 到范围内,实际用处很小 -
step属性不影响范围判定,但会影响用户能输入哪些值(比如step="0.1"时浮点精度问题可能让0.3被判为越界)
怎么写出真正起作用的警告样式
单靠 border-color: red 很难被注意,尤其在密集表单中。推荐组合使用:
- 边框 + 背景 + 阴影:
border-color: #dc3545; background-color: #fff5f5; box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.2); - 用相邻兄弟选择器显示提示文字:
#age:out-of-range + #age-hint::after { content: "需在 18–65 之间"; color: #dc3545; }(注意#age-hint必须紧跟在input后,且不能display: none) - 聚焦态单独强化:
input:out-of-range:focus加强box-shadow,但记得重置默认outline,否则和浏览器焦点环打架 - 别用
display: none或visibility: hidden隐藏越界输入框——这会让屏幕阅读器跳过,破坏可访问性
Safari 和移动端必须手动兜底
:out-of-range 在 Safari ≤15.4 中支持不稳定,旧版可能延迟触发甚至完全不生效;iOS 软键盘对 type="number" 支持不一,可能弹出数字键盘但允许粘贴字母——此时走的是 :invalid 流程,:out-of-range 完全不触发。
所以不能只靠伪类:
- JS 赋值(如
input.value = 150)后,必须手动调用input.checkValidity()或触发input事件才能更新状态 - 对非数字字符输入(如粘贴 “abc”),要用
input事件监听 + 正则拦截,或降级到:invalid:not(:out-of-range)处理 -
:out-of-range纯属 UI 提示,不阻止提交,也不修正值——后端或 JS 提交前校验不可省略
最易被忽略的一点:你无法用 getComputedStyle() 读取伪类状态,也不能用 JS 直接查 “当前是否在范围内”。只能监听 input 或 change 事件,再手动比对 element.valueAsNumber 与 min/max 属性值。


















