先记住这个答案
:in-range 和 :out-of-range 是表单验证伪类,用来判断输入框的当前值是否在 min 和 max 规定的范围内。比如 <input type="number" min="1" max="100">,用户输入 50 时匹配 :in-range,输入 150 时匹配 :out-of-range。这两个伪类只对有范围概念的输入类型有效,纯文本的 <input type="text"> 写了也不会匹配。
- 需要
min或max属性才生效 - 只对数字和日期类输入框有效
min、max决定范围边界- 空值不匹配
:out-of-range
哪些输入类型支持范围伪类
不是所有 <input> 都支持 :in-range。只有那些有数值或日期概念的类型才有范围可言。
/* 数值在范围内时绿色边框 */
input[type="number"]:in-range {
border-color: #2ecc71;
}
/* 超出范围时红色边框和背景 */
input[type="number"]:out-of-range {
border-color: #e74c3c;
background-color: #fdf2f2;
}支持的类型包括 number、 range、 date、 datetime-local、 month、 week、 time。这些类型都可以设置 min 和 max 属性来定义有效范围。
<input type="text"> 即使设置了 min 和 max 属性也不会匹配这两个伪类,因为文本输入没有数值范围的概念。想限制文本长度要用 minlength 和 maxlength,但那些不会触发 :in-range。
和 valid/invalid 的区别
:out-of-range 和 :invalid 经常同时匹配,但它们不是一回事。:invalid 的判断范围更广,包括格式错误、必填为空、范围超出等所有验证失败的情况。:out-of-range 只关心值有没有超出 min 和 max 的限制。
比如 <input type="number" required min="1">,用户什么都没填时,它匹配 :invalid(因为 required 没满足)但不匹配 :out-of-range(空值不算超范围)。用户输入了 0 时,两个都匹配。用户输入了 5 时,匹配 :valid 和 :in-range。
- 同时有 step 约束时
<input type="number" min="0" max="10" step="2">里输入 3,值在范围内但不满足step约束。这时匹配:in-range(值在 0~10 之间)但匹配:invalid(不是 2 的倍数)。这个细节面试偶尔会问到。
空值的特殊处理
一个容易混淆的行为:输入框为空时,既不匹配 :in-range 也不匹配 :out-of-range。空值不是 0,浏览器认为它「没有值」,不参与范围判断。
如果想在空值时也给出提示,需要和 :required 配合。用 :required:invalid 可以捕获必填但未填的状态,:out-of-range 只负责已填但超范围的情况。
容易答错的地方
- 以为只设置了 min 就不能匹配 in-range
- 只设置
min不设置max也能生效。:in-range会认为值大于等于min就在范围内(上限无穷大)。反过来只设置max也一样,值小于等于max就匹配(下限无穷小)。 - 以为 input type="text" 也能用
- 文本输入框、密码框、邮箱输入框这些类型没有数值范围的概念。即使写了
min和max属性,:in-range和:out-of-range也不会生效。
面试官还会怎么问?
input type="range" 会触发 out-of-range 吗?
正常情况下不会。滑块控件的值天然被限制在 min 和 max 之间,用户没法拖出范围。但如果用 JavaScript 的 value 属性强行设置一个超范围的值,滑块会被钉在最近的端点,值会被浏览器修正,所以 :out-of-range 几乎不会在滑块上触发。
怎么同时显示「超范围」和「具体超了多少」?
CSS 只能判断在不在范围内,不能读取具体的数值差。想显示「最大值为 100,你输入了 150」这样的提示,需要 JavaScript 读取 validity.rangeOverflow 以及 validity.rangeUnderflow 和元素的 validationMessage 来构造提示文案。
step 导致的不合法和超范围有什么区别?
step 约束失败(比如 step="2" 但输入了 3)不会触发 :out-of-range,因为值本身在 min 到 max 的范围内。它触发的是 :invalid。在 JavaScript 的 Validity API 里,对应的是 validity.stepMismatch,和 validity.rangeOverflow 是不同的标志位。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。