Good-Looking, Sharp Offset, CSS Text Styling

25th of November, 2006

It’s hard to describe this effect, which looking at the title is obvious. This is the kind of styling places like Joyent use in their level two headings, with a very slight white offset. Although theirs are buried within images, mine are CSS (with a little extra markup) and valid xHTML 1.0 strict.

I think it’s a very nice effect. One that’s obviously not for all text but is a nice decorative touch on headings and other special text. The problem with this effect before has been that it couldn’t be used in a dynamic situation, it had to be embedded with an image.

Starting work on a new WordPress theme today I wanted something a little better looking than flat text for the main headings, being a WordPress theme where the titles change contanstly between blog and post this style could not be embedded in a static image so I got to work on a CSS and (x)HTML version. Here’s the style.

h1 {
     color: #000;
     position: relative;
     }

h1 span {
     color: #fff;
     display: block;
     position: absolute;
     top: -1px;
     left: -1px;
     }

And the HTML markup to go with.


<h1><span>Lorem Ipsum</span>Lorem Ipsum</h1>

The extra text is within a display: block; span rather than a div which by default is blocked to keep things valid. Divs aren’t allowed in a h1, spans are. The colour you want for the top text is specified in the span and the offset colour is in the h1. You can style the h1 like normal after that, although don’t give it anything like padding or text-indent, that’s likely to stuff it up.

It’s definitely not accessible as the text has to be repeated twice. With styles turned off the heading text will be displayed twice, screen readers will read it twice and search engines will record it as written twice. Perhaps that’s the price to pay for pretty headings. I see it as better than a heading image with no alt tag. Providing the information twice is better than not providing it at all.

Tested and works in IE 6, IE 7, Firefox 2 and Safari. You can see the working example here.