Do you really want to use :nth-child selector?

This is not the first time I see someone run into this problem so I decided to write few words on this topic. So far I haven’t run into situation or a real need that I have to use :nth-child selector (although it seems to be more popular) instead of :nth-of-type, how often do you think “I want to select the second child of a parent if it just happens to be a paragraph.”. Of course, in the current version of your html you might can make your code to work, your java script or your css, but that can be untriggered bomb for anyone that will inherit your code and which is even worse that anyone can be you in the future.

nthchildVSnthOfType

It’s best to explain this with a practical example. Let’s say that we have a scoreboard with results from an athletic track race. Now we have a requirement that we need to color differently the first, second and third place to resemble the appropriate award – gold, silver or bronze. Let’s say that we have this html to display the result table

Implementation using :nth-child selector

This selector’s name implies that should be the logical choice, and for the current version of the html it will work perfect, and we’ll get the wanted award colors in the scoreboard. With this CSS we are selecting the first, second and third div in a section and apply the proper coloring.

nthChildCss.png

The results? As we expected!

nthChildInitialResults.png
This is the working example you can try yourself: https://jsfiddle.net/szLed4pp/7/

This is ok for now but what is someone adds another element in the section, lets say the client wants to have a heading/title that will describe the type of the event that the results are for, and after you add the h3 element your scoreboard html will look like this:

nthChildHtmlUpdate

Now we have the description header on our page but our CSS is broken and it’s now functioning as we expect it to do.

nthChildHtmlUpdateResults.png

This is the working example you can try yourself: https://jsfiddle.net/szLed4pp/10/

But why our CSS is not working after we added the h3 element?

That is because nth-child has strict conditions that the we are selecting the child at that position and the child at that position must be of the specified type, in our case div. After we added the h3 element the child at the first position is h3 so the first selector will not find any elements, the second selector will actually find the first div because that is the second child and it’s of type div, same applies for the third selector.

Implementation using :nth-of-type selector

Let’s see how we can implement the same requirement by using nth-of-type instead of nth-child selector. The CSS will be very similar to the previous one and we’ll use the same initial HTML for the example.

nthOfTypeCSS

The results? Again, as we expected!

nthOfTypeResults.png

This is the working example you can try yourself: https://jsfiddle.net/dL729cpv/6/

And now let’s say we have the same requirement, that the client wants to add heading/title to the scoreboard describing the event type. After the update, the element will look exactly as in the previous implementation.

nthChildHtmlUpdate

Now, let’s see the results after we made this update according to the client requirements.

nthOfTypeResultsUpdate.png

This is the working example you can try yourself: https://jsfiddle.net/dL729cpv/8/

Nothing is broken, everything works fine! This is because the nth-of-type selector is counting only the div elements (as in our example) and if add any other elements they will not be taken into consideration.

Conclusion

As you could see :nth-of-type is more practical and can be more of use than :nth-child. Also it seems to be more safe for further development and protects you (more) from code breaking after applying HTML updates.
:nth-of-type is supported by these Browsers: Firefox 3.5+, Opera 9.5+, Chrome 2+, Safari 3.1+, IE 9+… and also by jQuery 1.9…

So, remember this article next time when you say “Why is my :nth-child selector not working” 🙂

Happy coding,

J.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s