:out-of-range仅在input设min/max、type为number/date/time等且值合法时生效,不响应JS赋值,需checkValidity()或dispatch input事件触发;非数字输入、iOS粘贴、IE等需JS兜底。

:out-of-range 能用,但只在特定条件下触发视觉反馈——它不是实时监听器,也不是校验开关,更不替代 JS 或后端验证。
为什么写了 :out-of-range 样式却没反应
根本原因几乎总是以下三点之一:
-
input没设min或max属性(哪怕只写一个也行),伪类直接不匹配 -
type不是"number"、"date"、"time"等原生支持范围的类型;type="text"加了min="0"也完全无效 -
min/max值非法,比如min=""、min="ten"、min="10px",浏览器解析失败,伪类失效
调试建议:打开 DevTools,在 Elements 面板里手动改 value 为超界值(如 value="200"),再看该元素是否被标记为 :out-of-range 状态。
:out-of-range 不响应 JS 赋值,必须手动刷新校验状态
用 input.value = 150 或 input.setAttribute('value', '150') 后,样式不会更新——因为浏览器不把 JS 赋值当作用户交互,不触发原生校验流程。
立即学习“前端免费学习笔记(深入)”;
要让样式同步,必须补一步:
- 调用
input.checkValidity()(只刷新状态,不弹提示) - 或调用
input.reportValidity()(会弹原生气泡,适合提交前) - 更贴近用户行为的做法:赋值后
dispatchEvent(new Event('input', { bubbles: true }))
注意:input[type="range"] 几乎永远不触发 :out-of-range,因为它的值会被浏览器自动截断到 [min, max] 内,JS 赋越界值也读不到原始非法值。
怎么写出真正可见、可用的警告样式
单靠 border-color: red 很难被注意,尤其在密集表单中。推荐组合使用:
-
border-color: #e53e3e+background-color: #fff5f5+box-shadow: 0 0 0 2px rgba(229, 62, 62, 0.2) - 搭配
:out-of-range:focus强化聚焦态,避免干扰未激活字段 - 用相邻兄弟选择器显示提示文字:
#age:out-of-range + #age-hint::after { content: "需在 18–65 之间"; color: #e53e3e; } - 务必重置
outline(如outline: none),否则和浏览器默认焦点环打架
别用 display: none 或 visibility: hidden 隐藏越界输入框——这会让屏幕阅读器跳过,破坏可访问性。
移动端和兼容性必须手动兜底
iOS 软键盘对 input[type="number"] 支持不一:可能弹出数字键盘,但允许用户粘贴字母或符号。此时 :out-of-range 完全不触发,因为非法输入走的是 :invalid 流程。
所以不能只靠伪类:
- 必须用 JS 监听
input事件,用parseInt(e.target.value)实时判断数值是否越界 - 对非数字字符,用正则或
inputmode="numeric"+pattern="[0-9]*"辅助拦截 - IE 完全不支持
:out-of-range,旧版 Edge(12 之前)也不支持;现代浏览器中 Chrome 53+、Firefox 50+、Safari 10.1+ 均支持
最易被忽略的一点:伪类只是 UI 反馈钩子,它既不阻止提交,也不修正值,也不保证用户看到提示——所有关键逻辑仍得靠 JS 和后端双重保障。


















