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 support
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
Any | 3.2+ | Any | 9.5+ | 9+ | Any | Any |
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.
Thx for this!
Nice tip!
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.
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.
touche.
nice post too :)
and nice testing page.
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!
In the meantime, just use jQuery.
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.
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.
nth-child does not accept equations.
It accepts expressions.
I was also surprised to see the word “equation” in the text. That should be an expression.
Even more amazing – author still haven’t corrected it all these years!
Fair enough. I’ll change it. I can’t help but feel it’s a little pedantic but it also more correct.
Thanks for the Great Post Chris!
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.)
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.
Cool. I did not know you could do that with css. I might find a use for it in the future.
Seems like an awesomely simple way to handle zebra-striping tabular data.. aside, of course, from IE ruining the party as always.
I especially like the “first n elements” method.
Thanks Chris!
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.
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 ^^
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.
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
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:
see also :
http://api.jquery.com/nth-child-selector/
and:
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");
I am using jQuery and CSS3 selectors. the nth-child is a very powerful future.
Thanks for your very nice tutorial.
I’m skinning something today for which this will be EXTREMELY helpful. you rock!
Thanks for sharing this! Learning a ton from your articles!
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!
many thanks for this article, i am realized!!
It’s superb info and i immediate twitt it on twitter to know others. Thanks
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 :)
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.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.
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.
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)
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.
Anyway to select all children after the (e.g.) 5th one? So if we have 10 children, select 6-10.
Take a look at this article: https://css-tricks.com/useful-nth-child-recipies/
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?
Excellent explanation. I really appreciate the nth-child tester page. Thanks.
Hi Chris,
Thank you SO much for this great explanation!
Excellent example. Now I am facing problem and was hoping this would help me.
Making a grid system based on your https://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?
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.
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.