The :first-child conundrum

Update (April 24, 2024): Yeah, this is a really old post. :first-of-type has existed for years now. Maybe it even existed when I wrote this in 2012, but I wasn’t aware of it.


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.

Google: anatomy of a (half-assed) web redesign

There are many things Google is good at. Internet search and targeted advertising clearly being the top two. I use and appreciate several of Google’s products, especially Gmail, Google Reader and Chrome. But I only use Gmail as a reliable email provider with great spam filtering; I hate the web interface, and check my mail using the native mail clients on my Mac and iPhone. I use Google Reader solely to manage my subscriptions, whereas I actually read my RSS feeds, on all of my devices, with Reeder. And the only times I fire up Chrome are when I need to use Flash, per John Gruber. In general, I like Google’s products for the power of their underlying technologies, just as I hate them for their miserable user interfaces.

I think there are very few people who would consider design to be one of Google’s strong suits, from their traditionally un-designed home page, to their hideous logo (which, nonetheless, went through several apparently well-, or at least extensively-, considered revisions), to the notorious case where, engineers to the core, they logically weighed the relative merits of 41 shades of blue.

If you actually use any of Google’s websites directly, you’ve surely noticed in the last 24 hours that there has been a redesign. The most distinctive feature is the jarring black bar now at the top of all (well, most) pages. Personally I’d prefer something a little more subtle, but it’s tolerable, and presumably achieves its goal of getting your attention by being the only solid black area on your computer screen.

What really bothers me about this redesign is the lack of internal consistency as you dig deeper. To wit, let’s have a look at the landing pages of Google’s three biggest search tools (as determined by their placement in the black bar): Web, Images and Search:

The main things I notice about the main Google (Web) search page compared to the previous version are that the logo is slightly smaller (and appears to have been refined in terms of the extent of 1997-era Photoshop effects applied to it, although I think that change happened a few months ago), and that the “Google Search” and “I’m Feeling Lucky” buttons have been redesigned. They have very slightly rounded corners, an extremely subtle off-white gradient, and are set in dark gray Arial bold 11-point (or so) type.

On Google Images, the logo appears to be basically the same (although perhaps a bit more dithered), but it is much higher on the page. The search box itself is darker and has a drop shadow. The “Search Images” button is larger, has sharp corners and a more intense gradient, and is set in black Arial, larger and normal weight. If I’m not mistaken, this is how the buttons on most Google sites looked prior to yesterday’s redesign, so this appears mainly to be a case of Google Images not keeping up with the changes happening elsewhere.

The page is also cluttered up with instructions and a rather arbitrary set of four sample images. I never bothered to read that text or figure out why the images were there until just now as I was writing this article. Being able to perform a visual search by dragging a sample image into the search box is a really cool idea, but anecdotally I would suggest Google has a daunting challenge in educating users about it, if making it the only thing on the page besides the search box itself still doesn’t get the user’s (i.e. my) attention. Maybe their insistence on using undifferentiated plain text (while it might make Jakob Nielsen proud) for everything is part of the problem.

Google Videos is really the odd man out. A smaller logo, set too far down on the page, and a bright blue search button with no text, just a magnifying glass icon, that would look more at home on a Windows XP start screen than on a Google page. (Astute observers will also note from these screenshots that Google Videos, unlike Google Images and Google Web, displays a glowing focus state on the search box, which is due to the lack of :focus { outline: none; } on the CSS for that element.)

I realize this blue button is more of the direction Google’s heading and I do like it visually, even if I don’t think the search button needs to be so prominent on a page that contains very little else. But the thing that bothers me is the overall inconsistency between these tools.

Consistency is a big buzzword for me. To me it is absolutely the most important thing to consider in good UX and UI design. It doesn’t matter how novel your design elements are; if you present them consistently users will quickly learn how to use them and will gain confidence with your tools. They will also gain expectations that you then have to manage. These do impose limitations on you in the future, sure, but they also relieve you of the burden of having to reinvent every page.

Consistency demands a good style guide, something that is easy to overlook. And just as important as having the style guide is having the commitment to using it. That’s something even a company as big as Google clearly struggles with.

Fun with CSS in WordPress

I just had an email exchange with an old friend and fellow web developer (and WordPress user) regarding some techniques for CSS trickery on home pages in WordPress themes. Up until this week, I had been running a version of my theme that just featured brief excerpts of articles on the home page. I was doing this by brute force in PHP, truncating the post text with the substr() function, and then cleaning things up using the strip_tags() function, which removes all HTML tags from a string.

It got the job done, but as he and I were discussing, it wasn’t pretty: it stripped out the “dangerous” stuff — that is, unclosed HTML tags (cut off during truncation) that would have screwed up the formatting of the rest of the page. But it also stripped out desirable styling (bold, italics, links) and paragraph breaks.

The ideal situation would be to have a way to show just the first two paragraphs of each post, retaining all of their original formatting. Of course, WordPress has a feature to handle this: if you put a <!--more--> comment tag in your post, your page template can truncate the post at that point, with a link to the single-post page to display the rest of the content. But I’ve never liked having to put that <!--more--> into my posts. I want a completely automated solution.

And then it hit me… this could be done with CSS. It took a little trial and error, but I came up with the following:

#content .entry p,
#content .entry h3
{
display: none;
}

#content .entry h2:first-child,
#content .entry h2:first-child + p,
#content .entry h2:first-child + p + p
{
display: block;
}

A few things to note:

  • This assumes that your entire loop is wrapped inside <div id="content">...</div>. You may need to come up with a specific ID to use just for this block in your index page, and be sure not to use that in your single-post page, or your posts will never appear in their entirety.
  • This also assumes that you’re using the WordPress convention of wrapping your posts in a pair of <div> tags with the attributes class="post" and class="entry" (though technically, class="entry" is the only one that matters here).
  • Your post title should be in an <h2> tag, immediately following <div class="entry">.
  • The first definition may need to be extended to include other HTML tags you want to hide on your index page. In this example, it’s only hiding content that is inside <p> or <h3> tags.
  • If you want to hide every HTML tag except the ones you explicitly specify, you could change the first block to #content .entry *, but keep in mind that will also remove styling like bold and italics, and it will remove links. Probably not what you want.

The specifics may vary depending upon how your WordPress theme is set up; I just know that with the way mine is set up, which pretty closely follows standard convention, this CSS worked to get the index page to list the posts and only show the first two paragraphs of each. (It also retained the images that I embed at the start of each post, and also retains any embedded video from YouTube or Vimeo, since — at least the way I insert them — those are not wrapped in <p> tags.

Note that all of the HTML content for each post is still loaded by the browser — we’re just using CSS to tell the browser not to show it on the page. This is not going to help with performance; it’s strictly aesthetic.

Trying out a new look

I’m trying out another new look for this blog. This design will probably evolve over time, but I am excited about the new direction — most significantly, the new colors, and the custom fonts using @font-face in CSS. The fonts are from a site I just discovered and am very excited about: The League of Moveable Type (no relation to Movable Type, the blogging software).

Of course, Internet Explorer won’t support it, so the fonts degrade to more common, standard, and boring options.

Let me know what you think!

New Coltrane site launched

John Coltrane, Avant Garde Jazz and the Evolution of "My Favorite Things"
I’m pleased to announce the launch of a brand new version of my John Coltrane website.

This is the first step in an ongoing process of splitting my currently mammoth website into distinct, separate websites tailored to specific content areas. Basically, each of the top-level navigation items you see at the top of this page will eventually become its own site.

For now there’s not a lot of new content on the Coltrane site — the big “draw” is the redesign itself. But I’ve added a blog to the site, and eventually I’ll also be adding a multimedia section where I’ll be featuring audio and video clips. Check it out!

This site design was also an opportunity for me to test the effectiveness of my new Room 34 Baseline WordPress theme. Believe it or not, that barebones theme really is the foundation upon which the new Coltrane site is built. So it works!

This site also takes advantage of some cutting-edge web design features: it’s built with HTML 5 and the Blueprint CSS framework, and it uses the emerging @font-face CSS method to render text in a custom font. I am using the free Museo font family throughout the site.