Grow your CSS skills. Land your dream job.

How nth-child Works

Published by Chris Coyier

There is a CSS selector, really a pseudo-selector, called nth-child. Here is an example of using it:

ul li:nth-child(3n+3) {  
  color: #ccc;
}

What the above CSS does, is select every third list item inside unordered lists. That is, the 3rd, 6th, 9th, 12th, etc. But how does that work? And what other kinds of things can you do with nth-child? Let's take a look.

It boils down to what is in between those parentheses. nth-child accepts two keywords in that spot: even and odd. Those should be pretty obvious. "Even" selects even numbered elements, like the 2nd, 4th, 6th, etc. "Odd" selects odd numbered elements, like 1st, 3rd, 5th, etc.

As seen in the first example, nth-child also accepts expressions in between those parentheses. The simplest possible expression? Just a number. If you put simply a number in the parentheses, it will match only that number element. For example, here is how to select only the 5th element:

ul li:nth-child(5) {  
  color: #ccc;
}

Let's get back to the "3n+3" from the original example though. How does that work? Why does it select every third element? The trick is understanding the "n" and algebraic expression that represents. Think of "n" as starting at zero and then a set of all positive integers. Then complete the expression. So the 3n is "3xn", and the whole expression together is "(3xn)+3". Now substituting in the zero and positive integers, we get:

(3 x 0) + 3 = 3 = 3rd Element
(3 x 1) + 3 = 6 = 6th Element
(3 x 2) + 3 = 9 = 9th Element
etc.

How about the :nth-child(2n+1)?

(2 x 0) + 1 = 1 = 1st Element
(2 x 1) + 1 = 3 = 3rd Element
(2 x 2) + 1 = 5 = 5th Element
etc.

Hey wait! That's the same as "odd", so probably don't need to use that one very often. But wait now. Haven't we exposed our original example as being overly complicated? What if instead of "3n+3", we used "3n+0", or even simpler "3n".

(3 x 0) = 0 = no match
(3 x 1) = 3 = 3rd Element
(3 x 2) = 6 = 6th Element
(3 x 3) = 9 = 9th Element
etc.

So as you can see, the matches are exactly the same, no need for the "+3". We can use negative n values, as well as use subtraction in the expressions. For example, 4n-1:

(4 x 0) - 1 = -1 = no match
(4 x 1) - 1 = 3 = 3rd Element
(4 x 2) - 1 = 7 = 7th Element
etc.

Using "-n" values seems a little weird, because if the end result is negative there is no match, so you'll need to add to the expression to get it back positive again. As it turns out, this is a rather clever technique. You can use it to select the "first n elements" with "-n+3":

-0 + 3 = 3 = 3rd Element
-1 + 3 = 2 = 2nd Element
-2 + 3 = 1 = 1st Element
-3 + 3 = 0 = no match
etc.

Sitepoint has a nice reference guide, which includes this handy-dandy table which I'll shamelessly republish here:

n 2n+1 4n+1 4n+4 4n 5n-2 -n+3
0 1 1 4 - - 3
1 3 5 8 4 3 2
2 5 9 12 8 8 1
3 7 13 16 12 13 -
4 9 17 20 16 18 -
5 11 21 24 20 23 -

Browser Compatibility

nth-child is one of those rather unfortunate CSS attributes that is caught between nearly full cross-browser compatibility, except for completely zero support in IE, even IE 8. So when it comes to it's use, if the end result is "progressive enhancement" in some fashion (e.g. applying a cool color palette to table rows, for example), then by all means, go for it. But you probably shouldn't use it if you are doing something more important, like relying on it for site structure. For example, removing the right margin from every third box in a three by three grid of boxes, so they will fit properly.

One saving grace here is that if you are using jQuery, which supports all CSS selector including :nth-child, the selector will work, even in Internet Explorer.

Still not getting it?

I'm not a big fan of the phrase "I'm a visual learner". Of course you are, everybody is. Visual aids are enormously helpful in situations just like this. To help, I put together a little nth-child tester page. There, you can type in expressions and see the results of what it selects below.

Also see this page of useful nth-child recipes for quick copy-and-paste code on the most common positional selecting needs.

Comments

  1. Vincent
    Permalink to comment#

    Thx for this!

    Nice tip!

  2. Permalink to comment#

    Your patience with the rest of us continues to amaze me Chris.

    Well written, and more importantly, written in a manner that finally brings clear to me this concept.

    And that was ‘without’ the phrase “I’m a visual learner”
    :)

    Thanks for taking the time to do this, and for your sharing. You’ve definitely paid-it-forward.

  3. Permalink to comment#

    really nice post. Please place a retweet button in your posts so that it become easy to share on twitter.
    Thanks.

    • Not to sound like a wanker here, but retweet buttons take all the spirit out of Twitter if you ask me. If you like this (thanks!), then go up to the URL bar, copy the URL, go to Twitter, write a new tweet in your own words, and share the link.

      You might even have a way easier way to tweet (for example on my Mac I use Tweetie and I just press Command-Return and I have a new tweet window).

      This way:

      1) It doesn’t rip you away from my site with a pre-filled, soulless tweet

      2) People only do it if they sincerely want to share it, and do so with their own voice

    • That doesn’t sound wankerish, that sounds considered, fair and responsible. Good work :)

    • Hear, hear! Certainly made me rethink my Twitter activities.

    • True, but share buttons don’t necessarily have to be all up in your face, and can prove useful for a lot of people.

    • Permalink to comment#

      touche.
      nice post too :)
      and nice testing page.

  4. Wow, I have never even heard of that CSS selector. I thing the idea of progressive enhancement is a key selling point to most clients, except the first question out of their mouth is, “How will the site look on IE6 on a 800 x 600 screen resolution.” Love technology!

  5. bill
    Permalink to comment#

    In the meantime, just use jQuery.

  6. Permalink to comment#

    One thing I find a bit counter-intuitive about :nth-child is that it uses all of the siblings when determining which elements to style, but will only style those that match the selector passed to it.

    For example, if I have a page of text with p tags, a h1 tag and some h2 tags and, for some strange reason, I want to alternate the colours of the p tags, nth-child wouldn’t do this successfully.

    p:nth-child(2n) would style…

    h1
    h2
    p
    p – This paragraph
    p
    h2
    p
    p – This paragraph.
    p

    …which is the 2nd and 5th paragraph. Not what I would expect.
    Surely the only elements counted should be the p tags?

    Apologies if this doesn’t read too well.

    • Permalink to comment#

      Turns out I need :nth-of-type instead.

    • Not quite… You’d want to use adjacent sibling combinators:

      h1 + p + p { color: red; }

      demo

      :nth-of-type still would require those headers and paragraphs to be wrapped in a parent of some kind.

  7. Thanks for the Great Post Chris!

  8. I was absolutely trying to do this “removing the right margin from every third box in a three by three grid of boxes, so they will fit properly” last week. And though I knew that I’d need to use js to get around IE, I was having trouble getting the equation/expression right. For some reason, I had missed the entire Algebra thing.

    But thanks to your handy dandy refresher course, I get it now! ;-)

    (I took the easy way out and just added the right margin measure to my #wrap div for time being.)

  9. Matt
    Permalink to comment#

    When it comes to a case where one browser will support it, and another won’t. I tend to go with the Javascript option. If it doesn’t work well cross browser, it won’t be used as a critical element anyway, so implementing it in JavaScript should be a safe way to go. Cross browser, but not critical.

  10. Cool. I did not know you could do that with css. I might find a use for it in the future.

  11. Permalink to comment#

    Seems like an awesomely simple way to handle zebra-striping tabular data.. aside, of course, from IE ruining the party as always.

  12. Permalink to comment#

    I especially like the “first n elements” method.

    Thanks Chris!

  13. So nice – thanks for putting together this tutorial and the tester. I uses nth-child recently on a website to progressively fade out older Tweets.
    #tweets li:nth-child(2){opacity:.8;}
    Just a nice little look for good browsers.

  14. DexTroN
    Permalink to comment#

    Nice work explaining it for us who don’t remember our school math :D

    btw it’s called “pseudo” and not “pseduo” like in your first sentence ^^

  15. TeMc
    Permalink to comment#

    Another short little example.

    Say you want to style the top 3 and the top 10 in a special way of your top 100 list of something

    # HTML
    [ol id=ranking]
    [li]1. Lorem
    [li]2. Isum
    [li]3. etc.
    [/ol]

    # CSS
    #ranking li { default:style; }
    #ranking li:nth-child(odd) { zebra:style; }
    #ranking li:nth-child(-n+10) { special: styling; }
    #ranking li:nth-child(-n+3) { special: styling even better; }

    You the cascasing and overwriting principle of CSS to style everything the way you want.

    Pretty cool, huh ?

    • That looks like it’d be by far the best way to use this selector.

      I can’t imagine a lot of use for it otherwise, besides making viewing large chunks of the same type of tag a bit less repetitive/monotonous.

  16. Permalink to comment#

    this is awesome, so many tutorials go way over the complexities surrounding nth-child.

    But. Am i correct by saying, s’long as im requesting jquery into my site then the nth-child Will work, with no further work ?

    Cheers

    • TeMc
      Permalink to comment#

      No, jQuery doesn’t “fix” anything that’s within your css files. If you wanna use this the save way, for browsers that work with jQuery but not with CSS3, then you gotta do it in jQuery and not in CSS. For example:

      $("tr:nth-child(odd)").css("background", "#ff0000");
      
    • You can also have it apply classes instead, just for IE or browsers that don’t support this.

      For example:

      $("tr:nth-child(odd)").addClass("nth-child-odd");

  17. Permalink to comment#

    I am using jQuery and CSS3 selectors. the nth-child is a very powerful future.

    Thanks for your very nice tutorial.

  18. I’m skinning something today for which this will be EXTREMELY helpful. you rock!

  19. Antonio
    Permalink to comment#

    Thanks for sharing this! Learning a ton from your articles!

  20. Chad
    Permalink to comment#

    If you want to unselectively grab all elements within another, you can use

    element > :nth-child(blah){}

    For instance, I am coding a site that will be updated by people who shouldn’t need to know CSS in the future, and in order for pictures and text to be pretty within overlays, I needed to style everything but the close button and an image to have particular margins. Fortunately, these were the first two elements within each overlay, so I could use

    div.overlay > :nth-child(n+3){margin:0 10px 5px;}

    Thanks for making me think about using nth-child!

  21. anon
    Permalink to comment#

    many thanks for this article, i am realized!!

  22. It’s superb info and i immediate twitt it on twitter to know others. Thanks

  23. This is such great CSS, I just can’t believe that IE doesn’t support it. I mean I get why it might not render margin and padding the same (to name a few), but it really is awful that it doesn’t support such a technique. My life could be made a lot easier if I were able to use this for structuring sites…

    Thanks anyway :)

  24. Permalink to comment#

    The tester page ist not so usefull when you’re using JavScript to achieve the effects. Someone could think it will work in Internet Explorer (with plain CSS).

    It would be better to alternate the real CSS via JavaScript (thats setStyle(s) for MooTools, I don’t know the corresponding function in jQuery but it should be .css(...) or something like that) then using JavaScript directly.

  25. A progressive enhancement (at least for layout) way around the IE problem would be to use :nth-child(1n) along with the other :nth-child’s. That way, every child element get’s the code you need in browsers that support :nth-child, and for browsers that don’t support it, just make sure that the fallback doesn’t break the layout.

  26. What about if you want to have an alternating background color on a group of rows in a table?
    I have a whole page full of rows and I want them to be five-on and five-off (five with a light grey background and five with a white background, alternating all the way down the page).
    I’m not seeing how only addition and subtraction would solve that.

    • Permalink to comment#

      Hi Joshua,
      I would select every 5 as a group starting like this:
      ul li:nth-child(10n-5),
      ul li:nth-child(10n-6),
      ul li:nth-child(10n-7),
      ul li:nth-child(10n-8),
      ul li:nth-child(10n-9) {
      color: #ccc;
      }
      You just have to think, that you are actually grouping every 10th item (5on + 5off)

  27. Xirux Nefer
    Permalink to comment#

    My God Chris, why do you explain such a simple thing in such a complicated way…. XD

    the 2n only means that you take elements in bunches of 2, 3n in bunches of 3, etc. etc.
    the number you add or subtract just means where do you want to start.

    Example: 2 + 3n = “take elements in bunches of 3, start from the second”.

    That’s it, 3 sentences. Yeehaa!

    However, I am even more surprised at the people commenting that this is advanced algebra. Hell, if basic addition is advanced maths, then what have we done with our education system………………………. (now is when I go to the darkest corner of the room and cry for the future of humanity XD)

    • Normally a love an alternate explanation, but you just sound like a prick here. Feel free to re-post your explanation without the tone.

  28. Julian
    Permalink to comment#

    Anyway to select all children after the (e.g.) 5th one? So if we have 10 children, select 6-10.

  29. Hi, I relay like this post and many others, I have a situation in witch I want to select the elements in a list like this.
    for 1 2 3 4 – I used the default style
    for 1 2 3 4 – I used li:nth-child(3n-1):hover a{}
    for 1 2 3 4 – I used li:nth-child(3n-3):hover a{}
    Do you have any suggestions what I could use instead of the default style to select the first set of elements?

    • It seems that the colors didn’t make it to the post so I need to refraze.
      for 1, 4 in 1 2 3 4 5 6 – I used the default style
      for 2, 5 in 1 2 3 4 5 6 – I used li:nth-child(3n-1):hover a{}
      for 3, 6 in 1 2 3 4 5 6– I used li:nth-child(3n-3):hover a{}
      Do you have any suggestions what I could use instead of the default style to select the first set of elements?

  30. Brandon
    Permalink to comment#

    Excellent explanation. I really appreciate the nth-child tester page. Thanks.

  31. Adriana
    Permalink to comment#

    Hi Chris,
    Thank you SO much for this great explanation!

  32. dan
    Permalink to comment#

    Excellent example. Now I am facing problem and was hoping this would help me.
    Making a grid system based on your http://css-tricks.com/dont-overthink-it-grids/,
    problem I have is that on specific width I want to drop some divs and have their width be 100% .
    I was previously doing this via js and counted how many divs are inside the row but would love to do this via css only.

    col = 6 or 8 all 50% width
    col = 5 — 5th only 100% , all others 50% width
    col = 3 — 3rd only 100% , all others 50% width

    this is very hard to match since 3n will mess up the rows with 6 8 and 5 .
    Cant wrap my head around this.
    Any takers?

  33. Moritz

    May I try another very simple explanation? Leaving out the maths, Xn+Y means use every Xth element and start this selection at position Y. 6n+3 for example means use every 6th element and start this at the third element.

  34. Shab
    Permalink to comment#

    Great explanation, thanks!

    FYI, recent events directed me to read up on individual learning styles. It’s quite a study. In general, researchers measure learning preferences across many dimensions. The Felder-Silverman model, for example, has a visual-verbal dimension that reflects the learner’s retention ability for pictures or words. While it seems the population at large generally is somewhat better with pictures, this is not universal. I’m a visual learner (sorry!). My slightly autistic partner is very verbal.

  35. afs
    Permalink to comment#

    Nice

  36. hacker319
    Permalink to comment#

    Really nothing? That’s why you had to Google “how nth-child works”, read this whole page, and leave a comment?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".