CSS :in-range and :out-of-range Pseudo-Classes Explained

The CSS :in-range and :out-of-range pseudo-classes provide a native way to style form controls based on whether their current values satisfy specified minimum and maximum constraints. This guide explains how these selectors work with HTML number inputs, their requirements, practical code examples, and behavioral nuances to enhance client-side form validation.

How They Work

The :in-range and :out-of-range pseudo-classes target form controls that support range limitations—primarily <input type="number"> and <input type="range">, but also date and time inputs.

For these selectors to function, the input element must have min, max, or both attributes explicitly defined:

  • :in-range: Matches an element when its current value is greater than or equal to the min attribute and less than or equal to the max attribute.
  • :out-of-range: Matches an element when its current value is strictly lower than the min attribute or strictly higher than the max attribute.

HTML Structure

To use these selectors, define the range limits directly on the input element:

<label for="quantity">Select Quantity (1 to 10):</label>
<input type="number" id="quantity" name="quantity" min="1" max="10" value="5">

CSS Implementation

You can apply distinct styles to provide immediate visual feedback as users type or adjust values:

input[type="number"] {
  padding: 8px;
  border: 2px solid #ccc;
  border-radius: 4px;
  outline: none;
}

/* Styles applied when the value is between 1 and 10 */
input[type="number"]:in-range {
  border-color: #28a745;
  background-color: #f4fff6;
}

/* Styles applied when the value is below 1 or above 10 */
input[type="number"]:out-of-range {
  border-color: #dc3545;
  background-color: #fff5f5;
}

Key Behavioral Nuances

  1. Empty States: If an input is empty and not marked as required, it generally does not match :out-of-range, even if the field is blank.
  2. Missing Limits: If an input has neither a min nor a max attribute, it cannot have a range limit, so neither :in-range nor :out-of-range will match.
  3. Partial Limits: If only a min is specified, any value greater than or equal to that minimum is :in-range, and anything below is :out-of-range. The inverse applies when only a max is provided.
  4. Unsupported Inputs: Standard text inputs (<input type="text">) do not support numerical ranges; these pseudo-classes have no effect on them.

Using :in-range and :out-of-range enables lightweight, pure CSS visual cues for data entry, reducing the need for JavaScript validation scripts for basic boundary checking.