The CSS “n of selector” Syntax

The :nth-child pseudo-class has a lesser-known syntax that filters elements by a given selector first—before counting order is applied. This allows you to select, say, the second element among those that share a class, rather than the second child overall.

In a simple case with two .accent paragraphs, .accent:nth-child(2) will fail to style the second accented paragraph if that paragraph isn’t also the parent’s second child. But :nth-child(2 of .accent) matches correctly, because it narrows the selection pool to only .accent elements and then takes the second one.

Applying It to a Date Range Picker

This pattern becomes quite powerful for UI components. Consider a month-view calendar where users select a range between two dates. Although some JavaScript is required for the logic—CSS can’t toggle a checkbox—the bulk of the styling and much of the interaction logic can be handled with the “n of selector” approach.

Building the calendar layout itself takes only a few lines of CSS, with each date rendered as a checkbox inside a label. When a user clicks a third date, the range should adjust: if the new date falls after the current return date, it becomes the new return date; if it falls before the current start date, it becomes the new start date. The displaced old date is unselected.

Range Re-Adjustment Logic

The JavaScript side uses the checked state to determine what to do on each click. You can get the clicked date’s index, then compare it against the position of the existing checked dates:

Using :nth-child(1 of :has(:checked)), :nth-child(2 of :has(:checked)), and :nth-child(3 of :has(:checked)), the code can check whether the newly clicked date is the first, second, or third checked item, and uncheck the appropriate box to maintain a valid two-date range.

This approach avoids manual iteration over a list of checked dates in JavaScript. Instead, CSS selectors directly identify which element to target by its position among the checked group.

Range Styling in Purely CSS

The visual effect of a selected range is arguably even cleaner. When exactly two dates are selected, the calendar can color the dates between the first and second checked items with a pale blue shade.

The CSS applies that background to any .date element that comes after the first checked date (:nth-child(1 of :has(:checked))) via the general sibling combinator, but excludes the second checked date itself by combining with :not(:nth-child(2 of :has(:checked))).

The result: a straightforward visual range indicator, all without having to compute differences or loop over dates in JavaScript.