CSS Selectors :nth-child and the of S clause

CSS is an ever-evolving collection of specifications. That includes selectors. One of the features introduced by the level 4 selectors specification, is the of S clause used with the :nth-child() and :nth-last-of-child() pseudoclasses.

Both :nth-child() and :nth-last-of-child() — along with :nth-of-type() and :nth-last-of-type() — are tree-structural, child-indexed pseudoclasses. They accept an argument in the form An+b, where:

  • A is a step interval or multiplier for n;
  • b is an offset; and
  • n is a integer that represents the index of the child element, beginning with 1.

For example, :nth-child( 2n ) selects every even-indexed item, while :nth-child( -1n + 5 ) matches the first five children.1

The of S clause adds an additional filter. Its syntax is An+b of S where S is a selector. It matches the nth element of the elements matched by the selector, S. For example, :nth-child( 2n of .star ) matches every other element with the class .star, as shown in the image below.

10 SVG shapes, alternating hexagon and star shapes. Every other star is magenta.
How the of S clause changes which child elements are matched. View a demo (requires a WebKit-based browser such as Safari or GNOME Web).

To date, the of S clause is only supported in Safari and WebKit-based browsers, such as GNOME Web. It remains an open issue for both the Chrome/Chromium and Firefox projects.

of S and Specificity

As a pseudoclass, :nth-child() has a specificity score of 0,1,0. However, adding the of S clause increases the overall specificity by that of S. In other words, :nth-child( 2n ) has a specificity rank of 0,1,0, but :nth-child(2n of p) has a specificity of 0,1,1 due to its type selector p. A selector such as :nth-child( 3n of .items ) has a specificity value of 0,2,0 because it contains one pseudoclass and one class (.items).2

Keep in mind that when S is a type selector, it's the equivalent of using :nth-of-type(). A selector such as :nth-child( 2n of p ) matches the same elements as p:nth-of-type( 2n ) and has the same specificity score.

of S and the *-of-type pseudoclasses

Note that the of S clause does not work with the :nth-of-type() and :nth-last-of-type() pseudoclass selectors. Remember that the :nth-of-type() and :nth-last-of-type() work with type selectors such as p, h1, and div.

The specification does not define behavior for misusing an of S clause with :nth-of-type()/:nth-last-of-type(). Safari and GNOME Web ignore it; :nth-of-type( 3 of .items ) is treated as though it's :nth-of-type( 3 ).

Testing for of S support

CSS parsing and error handling rules dictate that browsers should ignore rules that they do not understand. You can safely use it in your CSS, although you may want to combine it with @supports and a fall back.

/* What to do if the browser DOES NOT support of S */
@supports not selector( :nth-child( 2n of .items ) ) {
    .items:nth-child( 4n + 1 ) {
       background: purple;
    }
}

:nth-child( 2n of .items ) {
    background: purple;
}

Using of S as an argument for querySelector() or querySelectorAll() will also fail in browsers that don't support it. In that case, you can test for support using the CSS.supports() method and the selector() function before using it in your code e.g.: CSS.supports( 'selector( :nth-child( 2n of .items ) )' ).


  1. Both the step interval, A and the offset, b can be positive or negative integers. All of these pseudoclasses also accept even and odd keywords as arguments (which are the equivalent of :nth-child( 2n ) and :nth-child( 2n + 1 )) When A or b is 0, you don't have to include them. 

  2. Read the Calculating a selector’s specificity section of the Selectors Level 4 specification if you need a refresher. 

Get CSS Master, third edition

Did you learn something from this blog post? You might like the third edition of CSS Master. It contains several nuggets of CSS joy like this one.

Buy now from SitePoint

Subscribe to the Webinista (Not) Weekly

A mix of tech, business, culture and a smidge of humble bragging. I send it sporadically, but no more than twice per month.

View old newsletters