More control over the :nth-child() selector with S syntax

This article is a translation of the original article “More control over :nth-child() selections with the of S syntax»

I also run a telegram channelFrontend in a navy way”, where I talk about interesting things from the world of interface development.

Pseudo-class selectors :nth-child() and :nth-last-child()

By using pseudo-class selector :nth-child() you can select elements in the DOM by their index. Using microsyntax An+Byou get fine control over which elements you want to select.

  • :nth-child(2): Selects the second child element.

  • :nth-child(2n): Selects all even children (2nd, 4th, 6th, 8th, and so on).

  • :nth-child(2n+1): Selects all odd child elements (1st, 3rd, 5th, 7th and so on).

  • :nth-child(5n+1): Selects the 1st (=(5×0)+1), 6th (=(5×1)+1), 11th (=(5×2)+1) child.

To interactively see how the An+B logic affects selections, use tester :nth-child.

But you can make a more creative choice if you omit the parameter A. For example:

  • :nth-child(n+3): Selects each child element starting from the third one (3rd, 4th, 5th and so on).

  • :nth-child(-n+5): Selects every child up to the 5th (1st, 2nd, 3rd, 4th, 5th).

Combine multiple such selectors :nth-child()and you will be able to select ranges of elements:

  • :nth-child(n+3):nth-child(-n+5): Selects every child from 3rd to 5th (3rd, 4th, 5th).

Using :nth-last-child()you can make selectors like this, but instead of counting from the beginning, you start counting from the end.

If you want to take it to the next level, you can use :nth-child() to applying styles to a group of elements when they reach a certain size (“Quantity Queries”) or style a parent element based on the number of its children.

Prefiltering with the syntax of S

New in CSS Selectors Level 4 – the ability to optionally pass a list of selectors to :nth-child() And :nth-last-child().

:nth-child(An+B [of S]?)
:nth-last-child(An+B [of S]?)

When of S is specified, the An+B logic only applies to elements that match the given selector list S. This means you can pre-filter the child elements before An+B does its thing.


For example, :nth-child(2 of .highlight) selects the second matching element that has the .highlight class. In other words: from all child elements with class .highlight choose the second one.

This is different from .highlight:nth-child(2)which selects the element that has the class .highlight, and which is the second child element.

In the demo below, you can see this difference:

  • Item matching :nth-child(2 of .highlight)has a pink outline.

  • Item matching .highlight:nth-child(2)has a green outline.

code pen

note that S is a list of selectors, which means it accepts multiple selectors separated by a comma. For example, :nth-child(4 of .highlight, .sale) selects the fourth element, which is either .highlightor .sale from many child elements.

In the demo below, the element corresponding to :nth-child(4 of .highlight, .sale)has an orange outline.

code pen

Zebra Revised

Classic use case :nth-child() is to create a table with zebra stripes. This is a visual technique in which colors alternate in each row of the table. This is usually done like this:

tr:nth-child(even) {
  background-color: lightgrey;

While this works well for static tables, it becomes problematic when you start filtering the contents of the table dynamically. When, for example, the second row becomes hidden, the first and third rows end up being visible, each with the same background color.

code pen

To fix this we can use :nth-child(An+B [of S]?)excluding hidden rows from the logic An+B:

tr:nth-child(even of :not([hidden])) {
  background-color: lightgrey;

code pen

Pretty cool, right?

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *