写了 :in-range 却没变色,是因为浏览器未进入范围判定:type 非 number、min/max 未同时设置、value 为空或非法;其判定仅依据 value 是否在 [min, max] 闭区间内,与 step、格式无关。

为什么写了 :in-range 却没变色?
不是 CSS 写错了,而是浏览器根本没进入范围判定流程。最常见原因有三个:
• type 不是 "number"(type="text" 加 min/max 完全无效)
• min 和 max 没同时设置(缺一个都不行,哪怕 min="0" max="999999")
• 初始 value 为空(value="")或非法(value="abc"),此时两个伪类都不匹配,直接回退到基础样式
input[type="number"]:in-range 的边界怎么算?
它只做一件事:判断当前 value 是否落在 [min, max] 闭区间内,不关心格式、step 或是否必填:
• value="10" + min="10" max="20" → 匹配 :in-range
• value="20" + 同上 → 仍匹配 :in-range(端点包含)
• value="10.5" + step="1" → 仍匹配 :in-range(step 不影响范围判断)
• value="abc" 或 value="" → 两个伪类都不匹配(不是 :out-of-range!)
JS 修改 value 后样式不更新怎么办?
直接赋值 input.value = "15" 不会触发伪类重计算,因为浏览器校验状态没被通知:
• 必须手动派发事件:input.dispatchEvent(new Event('input', { bubbles: true }))
• 或调用校验方法:input.checkValidity()(仅刷新状态)或 input.reportValidity()(弹原生提示)
• 注意:getComputedStyle(input).getPropertyValue('border-color') 无法读取 :in-range 状态——它不可查询,只能监听事件后手动比对 input.valueAsNumber 与 min/max
移动端和 Safari 兼容性要注意什么?
• iOS Safari ≤15.4 不支持 :out-of-range,或存在延迟触发问题
• :in-range 在所有现代浏览器中支持良好,但旧版 Safari 对整个范围伪类链的渲染可能不稳定
• 不要依赖 transition 直接过渡 :in-range 切换——它不支持 CSS 动画过渡,得改用 JS 控制 class + transition 配合 :valid/:invalid
真正容易被忽略的是:伪类只是 UI 钩子,不是校验代理。你永远没法用 JS 问“它现在是不是在范围内”,只能自己算;而用户删掉输入、粘贴非法字符、禁用 JS,都会让这个样式失效。别让它替你挡数据校验。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











