CSS :nth-of-class selector

One thing that bothers me with CSS :nth-of-type/:nth-child selectors is that you can’t combine them with CSS classes. The selector below for example won’t work as you’d first expect it to work:

.bar:nth-child(2) {
  color: red;

No, the selector above won’t color the second .bar element red, something I had somehow expected it to do. What the selector will target instead, is an element that is both .bar and :nth-child(2):

See the Pen .class:nth-of-type by Bramus (@bramus) on CodePen.

🐛 This article previously wrongly assumed that the browser would somehow know that .bar happens to be an article element. That assumption was incorrect and this post has been adjusted to no longer contain this error. Thanks to @simevidas for pointing this out.


To solve my problem, I’d be needing something like a :nth-of-class selector. Unfortunately no such selector exists nor is it currently proposed. What is proposed though, in the upcoming CSS Level 4 Selectors specification (aka “not CSS4” 😜), is an extension to the nth-child/nth-last-child pseudo selectors: the ability to add an extra "of S" part into those selectors.

The :nth-child(An+B [of S]?) pseudo-class notation represents elements that are among An+Bth elements from the list composed of their inclusive siblings that match the selector list S. If S is omitted, it defaults to *|*.

Given that, our wanted :nth-of-classselector becomes a reality:

article:nth-child(2 of .bar) {
  color: red;

Here’s a pen with the result:

See the Pen .class:nth-of-type by Bramus (@bramus) on CodePen.

If you’re using Firefox or Chrome you’ll see that the demo above is broken, as browser support for it is bad. Only Safari supports it at the time of writing.

💡 Shown above is a dynamic CanIUse.com image, showing an always up-to-date support table. By the time you are reading this browser support might have become better.

Other browser that currently don’t support it have meta-issues to implement CSS Level 4 selectors:

Please vote on those bugs mentioned above if you want those features to land in the browsers.

🗳 By massively voting on browser bugs we can “tell” a browser vendor that we’d like to see a certain feature land. Go forth and vote.


Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Join the Conversation


    1. That still selects the first .bar (as it happens to also be the 2nd element in the list)

  1. This is a workaround but since lists or rows are usually rendered using .map or by iterating, I added ‘even’ and ‘odd’ class names to every other element and then can target them in css without :nth-child.

    pseudo-react example:
    DIV className={‘my-class ‘ + (i%2 === 0 ? ‘even’ : ‘odd’)} /DIV

    .my-class.odd {
    background: grey

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.