The :first-child conundrum

I like to think I’m a pretty adept CSS developer. I may not have written the book, but I have a solid understanding of CSS and can do some sophisticated things with it.

But one place I always get snagged with CSS is in using the :first-child pseudoclass. The idea behind :first-child is that you can apply different styles to the first child element inside a parent element than for the rest of the instances of that child element inside the same parent.

A way I end up wanting to use it a lot is to give the first child different margins than the rest. Maybe most of them need margin-top: 2em; for instance, but I want the first one to be flush to the top of the parent by using margin-top: 0; to override the default margin.

The full CSS might end up looking like this:

div>h2 { margin-top: 2em; }
div>h2:first-child { margin-top: 0; }

And then that would be put together with some HTML like this:

<div id="content">

<h2>First header</h2>
<p>This is the first paragraph!</p>

<h2>Second header</h2>
<p>And, surprise! This is the second paragraph!</p>

</div>

So far, so good. The problem is, what if you stick something else into the <div> before the first <h2> that isn’t another <h2>? Say, something like this:

<div id="content">

<div class="floating_sidebar">This should be floating to
the right of the content.</div>

<h2>First header</h2>
<p>This is the first paragraph!</p>

<h2>Second header</h2>
<p>And, surprise! This is the second paragraph!</p>

</div>

You may have guessed at this point that I’m not describing a hypothetical situation here. This is a stripped-down version of exactly what I’m building right now. The problem is, now the first <h2> is no longer the first child element of the parent <div> overall, so the :first-child CSS gets ignored.

True, it’s not the first child element, altogether, inside the parent. But it is the first <h2> child inside the parent. I can understand how, in other circumstances — say, if the inserted <div> wasn’t a float — you’d want the h2:first-child not to apply here. But in general it seems to me that if you’re specifying a tag with your :first-child, it should only matter that it’s the first tag of that type under the parent, even if there are other different tags before it.

I guess the real solution here would be to create another pseudo-class that does what I want. Now I just need to convince the standards folks and the browser makers to do that.

Note: The sample HTML was kind of a mess when I originally posted this. That’s what happens when you write a blog post in a hurry before rushing out the door for a meeting. It has now been corrected, and I made some other edits for clarity while I was at it.