It seems like the :in-range
and :out-of-range
pseudo-classes work similar to the :valid
and the :invalid
pseudo-selectors. When this is applied, the input
always seems to be in of the two states and because of it the default selector never gets applied. A blank value is also getting treated as in the range (though it shouldn't be). The selectors spec doesn't seem to mention a handling for this case.
Ideally, I would recommend adding a default value for the field (like value="0"
) because it is anyway a mandatory field for you. But, if you feel that the default red background affects your UX in a bad way then have a look at the below workaround.
Adding required
attribute to the input
(because it is anyway mandatory) and using it along with the :valid
and :invalid
pseudo-selectors seem to produce the required output.
input:invalid
- Applied for default scenario or blank value because field is required and so a blank value means invalid.
input:in-range:valid
- Any value that is in range and is valid would meet this selector.
input:out-of-range:invalid
- Any value that is out of range and invalid only because it is out of range will match this selector and so red color would come only when the value is out of range.
Note to future readers: This is also not very correct because if I am a user, I would expect a blank value for a required field also to be invalid and have a red background. So, this may not be a suitable workaround for you. Please validate and use accordingly.
input:invalid {
background: white;
color: white;
}
input:in-range:valid {
background: green;
color: white;
}
input:out-of-range:invalid {
background: red;
color: white;
}
<h3> CSS range validation </h3>
Enter your age
<input type="number" min="1" max="100" required>