Using the :first-of-type pseudoselector instead of :first-child

Consider this case: you have a blogpost with an image, a heading, and some text. You want a little margin on the top of every heading to divide the different sections. Your HTML might look like this:

<article>
    <img src="photo.jpg" alt="A nice photo" />
    <h3>My heading</h3>
    <p>Text. Bla bla bla</p>

    <h3>Another heading</h3>
    <p>Even more bla bla</p>
</article>

Your CSS might looke like this:

img {
    float: right;
    margin: 0 0 10px 10px;
}

h3 {
    font-size: 24px;
    margin-top: 24px;
}

p {
    font-size: 16px;
    margin: 12px 0;
}

Now here’s a problem. The very first <h3> will have an ugly margin at the top, so it doesn’t line up with the image. How would you style it so that it won’t have a margin at the top? My first guess was to use the :first-child selector:

article h3:first-child {
    margin-top: 0;
}

However, that doesn’t work. The spec is not very clear about it: but here’s the problem: :first-child only selects the very first element and doesn’t care about the element you give it. That’s great if all your elements are the same (such as <li> elements in a list) but it sucks when having a case like this.

Fortunately, there’s a new CSS3 property that’s perfect for this case. It’s called :first-of-type and does exactly what you want.

article h3:first-of-type {
    margin-top: 0;
}

Browser support is mostly pretty good, although you’re out of luck on Internet Explorer 8 and earlier.

Add a comment