[Fixed] CSS :first-child not working correctly

Look into several ways to fix :first-child pseudo classes not working with CSS

Dec 19, 2022 | Read time 9 minutes

🔔 Table of contents

Introduction

A common way to make your CSS and web design cleaner and more concise is to use pseudo classes. Pseudo classes are just special selectors we can use in CSS to apply our styles.

In our case, we can use the :first-child pseudo-class to select the first HTML element in a container element. This is great when your HTML is dynamic and you want to apply styles to the first element (eg highlight or change background color).

Although sometimes using this can be confusing - I think it could be due to the name. In this post, I will go over some steps to troubleshoot issues with this, and consider some special scenarios!

Steps we can take to troubleshoot/ fix our :first-child issues:

  1. Verify that we are using the correct syntax for the :first-child pseudo-class. Make sure that there are no typos, etc
  2. Make sure that the element you are trying to select is correct. The :first-child pseudo-class will only apply to the first child of its parent element.
  3. Check that there are no conflicting stying with the :first-child pseudo-class.
  4. Check browser support and use alternatives like Javascript/ polyfills

Step 1: Verify that we are using the correct syntax for the :first-child pseudo-class.

The syntax to select the first child of a container is :first-child. Make sure that we are using the single colon (:) and not the pseudo-element selector (::).

Pseudo elements are “fake” elements that gets created, but not seen in the HTML mark up. Some examples include: ::after, ::before, etc

A common issue that I get is typos - eg misspelling “first” and “child” :)

Step 2. Make sure that the element you are trying to select is correct.

A common misunderstanding of using :first-child as the selector is targeting the wrong element.

Consider the following HTML:

<div class="container">
  <span>This is a span</span>
  <p>Test paragraph A</p>
  <p>Test paragraph B</p>
</div>

Now lets say we want to make the paragraph “Test paragraph A” with a red font and pink background. Its tempting to write the following CSS:

.container p:first-child {  Will not work!.
  color: red;
  background-color: pink
}

However, this will not work and nothing will be selected. This is because, we are using the p:first-child selector.

The actual :first-child of the .container element is the <span> element.

So when we say p:first-child, this means ONLY apply the styles if <p> is the first element of the .container!

To fix the above, we can do the following:

.container span:first-child { /*✔️ Spans will now work!.*/
  color: red;
  background-color: pink
}

Step 3. Check that there are no conflicting stying with the :first-child pseudo-class.

A common problem that you can encounter is the :first-child styling is getting overwritten by another style.

For example, you could have a styling that is more specific or using the !important keyword.

Lets consider the following example. We want to apply the first <span> font to have color of red and we have the first selector using :first-child and the second using a class .my-span

<div class="container">
    <span class="my-span">XXX</span>
    <span>YYY</span>

</div>
.container :first-child { /*❌ Will not work! */
  color: red;
}

.container .my-span { /*✔️ This is more specific than the above */
  color: blue;
}

Due to CSS classes having higher specificity than pseudo classes, the font color of blue will be applied.

What is CSS specificity?

Specificity is how browsers decide on which style to apply to which element. Based on the CSS selector is an order in which styles will be applied!

Generally, selectors with IDs will override classes. In turn, CSS selectors with classes will override pseudo-classes such as :first-child!

Check here for more info on CSS specificity: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Step 4. Check browser support and use alternatives like Javascript/ polyfills

Support for :first-child pseudo class is generally good across most modern browsers. Only browsers that have issues include IE7 and IE8.

For example, it does not update the styles when the first-child is added dynamically.

Selecting :first-child of :first-child

A interesting use case is to select the first child of the first div.

To select :first-child of :first-child element, we can use the following syntax (keep in mind the space between them):

:first-child :first-child

Consider the following HTML - the first-child of the first-child of the .container class is the A1 <span>

<div class="container">
  <div>
    <span>A1</span>
    <span>A2</span>

  </div>
  <div>B</div>
  <div>C</div>

</div>

We can highlight the background of A1 to red using the following CSS selector:

.container :first-child :first-child{
  background-color:red
}

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

The difference between :first-child and :first-of-type is that :first-child is less specific. What this means is that using :first-child will always select the first element of a given parent element.

As for :first-of-type it will select the first element of a type for a given parent element!

Getting the :first-child of class

A common misconception of using :first-child with CSS classes is expecting it to select the first child element with a specific class. This is not correct! When we try to add a class .my-class:first-child, this just means that we ONLY select the first child of a parent element if it has a class of .my-class.

For the intended purpose of selecting the first element that has certain class, you will need to use the :first-of-type pseudo class!

The :first-child will select the very first child of the parent.

Consider the following HTML,

<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>

And now we try to select the first red element in the .home class:

.home .red:first-child { /*❌ Will not work! First-child refers to the span element*/
    border: 1px solid red;
}

.home .red:first-of-type { /*✔️ Will select the first red class! */
    border: 1px solid red;
}

This will not work, because the :first-child is the <span> element (blah)! To get the intended result, we should change the first-child selector to the : first-of-type

Browser support

:first-child is well supported across most modern browsers. Theres issues with Safari when we trying to select the first-child with no parent.

IE issues

  • Internet Explorer 7 doesn’t update :first-child styles when elements are added dynamically.
  • In Internet Explorer 8, if an element is inserted dynamically by clicking on a link, then the :first-child style isn’t applied > until the link loses focus.

Summary

In this post we went over some common issues when using the first-child pseudo class. There are a few steps to take - the first is to make sure that you are using the correct syntax - eg no spelling mistakes!

The main cause of these issues is misunderstanding of what the :first-child is supposed to do. It only the selects the immediate first child of a given element.

If you want to select the first element of a given CSS class (or tag), we will need to use the :first-of-type pseudo class instead!

Other things to check include checking the CSS specifity rules - for example other class styles or use of the !important keyword that could be overriding your :first-child styles.

Additionally, we should check the browser support - for example keep in mind Safari issues when dealing with first-child selectors that match elements with no parent!

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube