Demystifying CSS Pseudo-Classes (:nth-child vs. :nth-of-type)

Styles are applied to a web page using CSS selectors; selectors which make it possible for you to target a specific element or sets of elements. Usually, when you are starting with CSS, you’ll make use of element selectors before pivoting to use classes and IDs.

As powerful as these selectors are, they can be quite limiting, making it impossible to select an element based on its state. If you’ve ever worked with frontend frameworks like React and Vue, you possibly understand what state means. I am not referring to the overall state of the application, but the state of elements within the HTML code.

The humble link is a simple example–it can be created using an anchor tag <a>. The link can then have different states:

  • before the link is clicked
  • when a user hovers a mouse cursor over the link
  • when the link has been visited

Selectors used to target elements depending on their state are called pseudo-classes. nth-child and nth-of-type are pseudo-classes which select an element based on its position (the position of the element is also considered a state). Let’s take a closer look.

nth-child and nth-of-type pseudo classes

How to Work with :nth-child()

The nth-child pseudo-class is used to select an element based on its position in a list of siblings. There are things to take note of here:

  • Siblings: where a parent and children elements are present. In selecting a sibling you’re trying to target a specific child of the chosen parent. A ul and bunch of li are examples of parent and children elements.
  • The position of the element in the list of its siblings is determined by values that are passed to the pseudo-class.

We’ll be making use of the HTML code below to learn how nth-child works.

There are two different ways of specifying the position of the element: the use of keywords and functional notations.

:nth-child(even/odd)

If using keywords you can specify elements whose position is either an even or an odd number, like this:

This gives us the following:

:nth-child(2)

When we specify a particular number (like the 2 in this example), we’re selecting the element in the list of siblings whose position matches the number we’ve passed. Here we’re targeting the second child of the unordered list.

You can probably imagine what the result looks like:

One common pitfall here is after specifying the element, you might add a new element (like a heading) to the parent without realising the selected element will change. To show this, let’s add a heading to the list like this:

Even though this is actually invalid use of HTML, browsers will still render it fine, and in this case the first li element will be selected as it is now the second child of the unordered list.

:nth-child(An)

Okay, now we’re taking it up a notch. Here the elements (plural) we select will be determined using functional notation. n denotes a counter and  A represents the size of the cycle, giving us a sequence. For example, when we pass 2, it will select elements in the sequence 2, 4, 6, and so on:

To see it in action, let’s go back to our HTML code and add a few items to the list. We’ll also make the list an ordered list so that we can clearly see the items’ numbers:

Our result is as follows:

:nth-child(An+B)

Here we’ve added an extra calculation to our cycles: +B. The elements whose position in the list of siblings matches the pattern will get selected. We need to know how the calculation happens, so let’s try a functional notation like this:

This will select the items whose position matches 1, 4, 7, 10, and so on:

The calculation starts counting from 0, which is the default value of n, and as such the elements to be styled will be calculated like this:

  • First Element: 3(0) + 1 = 1.
  • Second Element: 3(1) + 1 = 4.
  • Third Element: 3(2) + 1 = 7.
  • Fourth Element: 3(3) + 1 = 10.

Think of it as an algebraic equation where the value of n increases arithmetically, and the element to be styled is the result of the equation. Here is another example, which you can edit yourself to see what happens:

You can also use this method to select even numbers, using the formula:

And odd numbers can be selected using:

How to Work with :nth-of-type()

In all the examples we have seen for the nth-child pseudo-class, it is important to note that the goal is to select elements in a list of siblings. This does not take into account the element type. To ensure the selection is also scoped to a particular type, we can make use of the nth-of-type pseudo-class.

To see this at work let’s edit the HTML code to look like this (again, this is technically misuse of HTML, but browsers will interpret it just fine):

To select the li elements whose position is an odd number, we can do this,

which gives us:

To select the li elements whose position is an even number, we would do

You may think that using nth-child would work just as effectively as long as you’re specifying the li, for example:

but that isn’t the case. Try it yourself!

Conclusion

These pseudo-classes come in handy when you have to select specific elements in a list of siblings. To learn more about them, check the MDN Web Docs for nth-child() and nth-of-type().

More CSS Fundamentals

Learn more about CSS, and CSS selectors with these fundamental guides: