:in-range 无反应的主因是HTML结构不达标,需type="number"(或date/time)且min/max合法、value为有效数字并落在闭区间内,否则伪类不触发。

为什么写了 :in-range 却完全没反应?
最常见原因是 HTML 结构不达标,不是 CSS 写错了。浏览器只对 type="number"(或 date/time)且带合法 min 和 max 属性的元素触发这两个伪类:
- type="text" 加了 min/max 也无效,它根本不走数值校验流程
- min 或 max 为空、含单位(如 max="100px")、或写成 min="auto",浏览器直接忽略该属性
- 初始 value 为空字符串或非法值(如 "abc"、"12a"),此时既不匹配 :in-range 也不匹配 :out-of-range
- 移动端旧版 WebView(如部分 Android Chrome)可能不支持,iOS Safari 从 15.4+ 开始稳定支持
:in-range 和 :out-of-range 实际触发条件是什么?
它们只判断「当前值是否为有效数字,且落在 min~max 闭区间内」,其余所有情况都回退到默认样式:
- 输入 "5",min="0" max="10" → 匹配 :in-range
- 输入 "105",max="100" → 匹配 :out-of-range
- 输入 " "、""、"--"、"12.5a" → 两个伪类都不匹配
- step 属性不影响范围判断,只影响 :valid/:invalid
- type="range" 永远匹配 :in-range(浏览器强制截断值),:out-of-range 几乎不会触发,别在这上面浪费样式
JS 赋值后样式不更新怎么办?
直接写 input.value = "200" 不会触发伪类重算,因为浏览器校验状态未刷新:
- 调用 input.checkValidity() 可静默刷新状态,适合后台赋值后同步视觉
- 调用 input.reportValidity() 会弹原生提示,适合提交前校验
- 更贴近用户行为的做法:赋值后立即 input.dispatchEvent(new Event('input', { bubbles: true })),让浏览器重走完整输入流程
- 别试图用 getComputedStyle(input).getPropertyValue('border-color') 判断状态——伪类无法通过 JS 读取
怎么让视觉反馈真正有用,而不是只改个边框色?
单靠 border-color 很难被注意,尤其在密集表单中:
- 对 :out-of-range 组合使用 background-color + box-shadow(如 box-shadow: 0 0 0 2px #e53e3e33)+ 文字色变化
- 用相邻兄弟选择器显示提示文字:#age:out-of-range + #age-hint::after { content: "需在 18–65 之间"; color: #e53e3e; }
- 避免用 display: none 或 visibility: hidden 隐藏提示,这会破坏屏幕阅读器可访问性
- 优先级冲突时,用更具体的选择器,比如 input[type="number"]:in-range,别依赖 !important


















