Comparing CSS Pseudo-Classes: nth-child vs nth-of-type

Jess Mitchell

CSS has a number of pseudo-classes to help you style your app with ease. Having lots of options can be great, but it can also be confusing to know which pseudo-class to use and what it really does. Here we’ll look at CSS’s nth-child and nth-of-type pseudo-classes to get a better understanding of when to use each and what the actual difference is.

The nth-child and nth-of-type CSS pseudo-classes are interesting compared to other types of pseudo-classes because they select elements based on their position in the DOM. Whereas some pseudo-classes select a specific state of an element (e.g. the hover, active, target pseudo-classes), nth-child and nth-of-type are more concerned with the structure of your markup.

Setting Up Our HTML

To understand the difference between nth-child and nth-of-type, let’s first build our HTML to know what we’re going to be styling.

Let’s say we have a section on our webpage that has a mix of header (<h1>, <h3>) and paragraph (<p>) elements.

<article>
  <h1>Here's a Header</h1>
  <p>I'm a paragraph with all kinds of information.</p>
  <p>Let's add another paragraph for fun.</p>
  <p>yadda yadda yadda</p>
  <p>blah blah blah</p>
  <p>yadda yadda yadda</p>
  <h3>Here's a Subheader</h3>
  <p>blah blah blah</p>
  <p>And maybe just one more.</p>
</article>

This markup will look something like this:

Markup with no pseudo-class applied

In total, we have an <article> element as the parent, and nine child elements: one <h1>, one <h3>, and seven <p> tags.

nth-child and nth-of-type Syntax

There are a few options for what values you can pass the nth-child and nth-of-type pseudo-classes. Note: nth-child is used here but it can be replaced with nth-of-type too.

  • :nth-child(2n+3): This option requires some math. The numbers are up to you; it’s the n that will vary. This will take your selected elements, set n to 0 to start, and increment from there. So, similarly to a for loop in JavaScript, it will iterate through your selected elements by updating the n value: 2(0)+3 = 3, 2(1)+3 = 5, 2(2)+3 = 7, and so on. The result of this will be selecting the third, fifth, seventh, etc. elements.
  • :nth-child(odd/even): The strings odd or even can be passed to select the odd and even elements available.
  • :nth-child(3n): You can also pass a number with the n variable, which will select that interval of the selected element’s occurrence. If 3 is passed, it will select the third, sixth, ninth, etc. elements.
  • :nth-child(3): If you just pass a number (without the n), it will select that element from the DOM specifically. Passing 3 will select the third matching element only.

Using CSS’s nth-child Pseudo-Class

The nth-child pseudo-class has two important components to consider:

  • the element(s) selected that will have the pseudo-class applied to it/them
  • the value passed to the pseudo-class.

If we go to our CSS stylesheet for the HTML example above, we can select our paragraph elements and make the font color maroon like so:

article p {
  color: maroon;
}
Markup with no pseudo-class applied

Let’s say we want every other paragraph element to be a yellow-ish color, though. (An “interesting” style choice… 🙈) We can apply the nth-child pseudo-class to only apply the new color to every other child element that’s a paragraph.

article p:nth-child(odd) {
  color: goldenrod;
}
Markup with the nth-child pseudo-class applied

Now our paragraphs alternate colors, but did you notice what happened after the sub-header? The maroon color was repeated and then switched back to yellow. Let’s look at why that happened.

Determining Which Elements are Selected with nth-child

In our example above, the paragraphs that match our p:nth-child(odd) styling have to meet the following requirements in this order:

  • they are an odd child of the parent element
  • they are a paragraph element

Determining whether the child is odd or even is not type-specific. That means the odd/even check looks at all the children in the parent element of what is being selected (the paragraph elements) and then looks for all the paragraphs that are considered odd elements.

Markup with the nth-child pseudo-class applied, plus annotations

The paragraphs that have the yellow font styling applied are “odd” children elements and they are paragraph (<p>) elements. 👩‍🎤 That explains why the paragraph after the sub-header ends up being the default maroon color– it’s actually an “even” child!


Using CSS’s nth-of-type Pseudo-Class

The nth-of-type is very similar to the nth-child pseudo-class. The main difference is that it specifically considers the type of the element getting selected before checking any other logic.

Let’s use our example from above but apply nth-of-type instead.

<article>
  <h1>Here's a Header</h1>
  <p>I'm a paragraph with all kinds of information.</p>
  <p>Let's add another paragraph for fun.</p>
  <p>yadda yadda yadda</p>
  <p>blah blah blah</p>
  <p>yadda yadda yadda</p>
  <h3>Here's a Subheader</h3>
  <p>blah blah blah</p>
  <p>And maybe just one more.</p>
</article>
article p {
  color: maroon;
}

article p:nth-of-type(odd) {
  color: goldenrod;
}

The default color is still maroon but now we’re selecting the odd paragraph elements only.

Markup with the nth-of-type pseudo-class applied

The styles are now applied if the element meets the following requirement:

  • the element is a paragraph with an article element as a parent
  • of the paragraphs selected above, only odd ones are selected

If we look at this again with the annotations, it’s a little clearer how these are getting selected.

Markup with the nth-of-type pseudo-class applied, plus annotations

The headers (<h1>, <h3>) are not considered at all with nth-of-type because we’re selecting by the element type specifically. We only care about the <p> elements in this case. 🔥


Whether you use nth-child or nth-of-type will ultimately depend on what your goal is for styling. (Classic “it depends” answer, right? 🤓)

As a general rule, if you want to select an interval of a selector regardless of the type of element it is, use nth-child. However, if you want to select a specific type only and apply an interval selection from there, use nth-of-type. 🥳


Browser Support

The nth-child and nth-of-type selectors both have excellent browser support. Check nth-child and nth-of-type on CanIUse.com for more details. You shouldn’t have any issues with either unless you’re supporting IE8 or lower. 🙈

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#