:out-of-range 无效主因有三:未设 min/max、type 不支持范围(如 text)、min/max 值非法;其匹配非实时,依赖解析成功+blur/submit;空值或非法字符不触发;JS 赋值需手动派发 input 事件;样式需组合背景、阴影、提示文案并重置 outline;它仅视觉提示,不可替代 JS 或后端校验。

为什么写了 :out-of-range 样式却完全没反应
几乎总是以下三点之一:input 没设 min 或 max 属性(哪怕只写一个也必须写);type 不是 "number"、"date"、"time" 等原生支持范围的类型(type="text" 加了 min="0" 也完全无效);min/max 值非法,比如 min=""、min="ten"、min="10px"——浏览器解析失败,伪类直接不匹配。
:out-of-range 的“即时”其实是假象,真实触发时机很关键
它不会在用户按下每个键时实时更新,而是在输入值被浏览器成功解析为有效数字、且失去焦点(blur)或表单提交时才稳定匹配。部分 Chrome/Firefox 在输入过程中会尝试更新,但 Safari ≤15.4 基本不响应,移动端尤其明显。
- 空字符串(
value="")或非法字符(如"abc")不会进:out-of-range,而是进:invalid - JS 直接赋值
input.value = "200"不会触发伪类更新,必须手动派发事件:input.dispatchEvent(new Event('input', { bubbles: true })) - 想“看起来即时”,得配合
input事件监听 + 手动比对input.valueAsNumber与min/max
怎么写样式才能让用户真正注意到越界
仅改边框色太弱,密集表单里根本看不出来。推荐组合反馈:
- 加背景色和阴影:
input:out-of-range { background-color: #fff5f5; box-shadow: 0 0 0 2px rgba(229, 62, 62, 0.2); } - 用相邻兄弟选择器显示提示文案:
#age:out-of-range + #age-hint::after { content: "需在 18–65 之间"; color: #e53e3e; },注意#age-hint必须紧跟在input后且不能display: none - 重置
outline:否则和浏览器默认焦点环打架,建议写成outline: 2px solid transparent
别把 :out-of-range 当校验逻辑用
它纯属视觉提示,不阻止提交、不抛错、不调用 JS 回调。你仍需:
立即学习“前端免费学习笔记(深入)”;
- 用
input.validity.rangeOverflow/rangeUnderflow在 JS 中做精确判断 - 提交前调用
form.checkValidity()或input.reportValidity() - 后端必须重新校验——前端样式可被绕过,
:out-of-range状态甚至无法用getComputedStyle()读取
最易被忽略的一点:伪类状态无法被 JS 直接查询,也不能替代任何实际校验步骤。


















