1

input {
  background: white;
  color: white;
}
input:in-range {
  background: green;
  color: white;
}
input:out-of-range {
  background: red;
  color: white;
}
<h3> CSS range validation </h3>
Enter your age
<input type="number" min="1" max="100">

Aim:

  • white for out-of-range (default case)
  • green for in-range
  • red for out-of-range

In the above snippet, how can one make

input {
   background: white;
   color: white;
}

work for just input regardless of in-range or out-of-range?

Harry
  • 87,580
  • 25
  • 202
  • 214
Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219

2 Answers2

3

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>
Harry
  • 87,580
  • 25
  • 202
  • 214
1

CSS cannot check whether or not a text box is empty under the conditions you are looking for. Below is a better approach to the solution, however your solution will require JavaScript. Please see this thread.


Try adding a class where the styles are only applied if the classes are on the element.

CSS

input[type="number"] {
    background: white;
    color: black;
}
input[type="number"].validate:in-range {
    background: green;
    color: white;
}
input[type="number"].validate:out-of-range {
    background: red;
    color: white;
}

HTML

<h3> CSS range validation </h3>
Enter your age
<input class="validate" type="number" min="1" max="100">

<h3> NO CSS range validation </h3>
Enter your age
<input type="number" min="1" max="100">
Community
  • 1
  • 1
William Callahan
  • 630
  • 7
  • 20