Selecting a Range of Elements with :nth-child()
Picking out elements between two fixed indexes with CSS is a surprisingly easy task that tends to trip people up. The trick is chaining two :nth-child() selectors together, and the logic bends a bit if you expect the selectors to behave like a union rather than an intersection.
Start at an Index and Go Up
Selecting from a certain index onward is straightforward:
div:nth-child(n + 2) {
}
/* [ ] [x] [x] [x] [x] [x] [x] [x], etc. */
Here, when n starts at 0, the expression evaluates to 2 and grows with every increment, matching the second element and everything after it.
Cap the Range from the Top
To create an upper bound, invert the direction of n:
div:nth-child(-n + 6) {
}
/* [x] [x] [x] [x] [x] [ ] [ ] [ ], etc. */
This matches only the first five elements. As n increases, the computed value drops to 0 and then into negative indexes, so nothing past the fifth element qualifies.
Combining Both Boundaries
The key insight is that multiple pseudo-selectors on the same rule are additive in the sense that every condition must be true for an element to match. It’s not that :nth-child() expressions accumulate matches; it’s that each element must independently satisfy both expressions.
To select elements two through five, chain the two selectors together:
div:nth-child(n + 2):nth-child(-n + 6) {
background: green;
}
An element must be at index 2 or greater and at index 5 or less to qualify. That intersection gives you exactly the second through fifth elements.
This pattern of nesting multiple nth-style pseudo-selectors is also the foundation of quantity queries, where you can apply styles based on how many total elements exist in the DOM.
div:nth-last-child(n+2):nth-last-child(-n+5):first-child,
div:nth-last-child(n+2):nth-last-child(-n+5):first-child ~ div {
/* Only select if there are at least 2 and at most 5 */
}


