CSS :first-child vs :first-of-type Explained

CSS pseudo-classes allow developers to style elements based on their structural position within a parent container. While both :first-child and :first-of-type target initial elements, they behave differently when evaluating an element's position versus its tag type. This guide explains how each selector functions, highlights the critical differences between them, and demonstrates when to use each in web development.

What is the :first-child Selector?

The :first-child pseudo-class represents the very first child element inside its parent container. When you attach a tag selector to it (e.g., p:first-child), the selector checks two conditions:

  1. The element must be the absolute first child of its parent.
  2. The element must match the specified tag type.

If another element precedes it—such as an <h1> placed before a <p>—the p:first-child selector will fail and match nothing.

p:first-child {
  color: blue;
}

In this case, a <p> element will only turn blue if it is physically the first sibling inside its parent.

What is the :first-of-type Selector?

The :first-of-type pseudo-class represents the first element of its specific tag type among a group of sibling elements. Unlike :first-child, it ignores preceding elements of different types.

When you write p:first-of-type, the browser scans through the siblings until it finds the first occurrence of a <p> tag, regardless of where it appears in the DOM order.

p:first-of-type {
  color: green;
}

Even if the <p> is preceded by an <h1>, <div>, or any other element, it will still match and turn green.

Code Comparison

Consider the following HTML markup:

<article>
  <h1>Article Heading</h1>
  <p>First paragraph.</p>
  <p>Second paragraph.</p>
</article>

Applying :first-child:

p:first-child {
  color: red;
}

Result: Neither paragraph changes color. The first child of <article> is <h1>, not <p>, so the rule does not apply.

Applying :first-of-type:

p:first-of-type {
  color: red;
}

Result: "First paragraph" turns red. Even though <h1> is the first child of the parent, "First paragraph" is the first <p> element among the siblings.

Key Differences Summary

  • Positional Strictness: :first-child strictly checks position index 0 of the parent. If the tag does not match index 0, it fails. :first-of-type searches down the sibling list until it finds the first match for that element type.
  • Tag Awareness: :first-child applies regardless of tag unless explicitly combined with one, whereas :first-of-type evaluates elements based on their HTML tag name.
  • Use Case: Use :first-child when an element must specifically be the first item rendered in a container (such as removing top margins from the first item in a list). Use :first-of-type when you want to target the first instance of a component (such as styling an introductory paragraph) where other elements like headers or images might come first.