//Monday 23 June 2008

CSS Image Replacement Techniques

Web designers like to use images for text because they can use non-standard fonts and have them nicely anti-aliased. There are a number of techniques out there that allow you to make this kind of image text accessible and search-engine friendly.

One technique I have seen used is a negative text-indent (see http://phark.typepad.com/phark/2003/08/accessible_imag.html).

For example, if you wanted to use an image for your h1 tag you could write something like this:


<h1 id="hello-world">Hello World</h1>

and then in your CSS you set a background-image for the hello-world element and set text-indent to a very large negative number so that it's rendered off the screen.

#hello-world
{
width: 100px;
height: 25px;
background: url(helloworld.gif) no-repeat;
text-indent: -9999px;
}

Most users will see the image but without the style sheet the h1 renders as normal. So search engines and screen readers should read your page in the expected way.
Note: I have read in articles that this technique does indeed work with the JAWS screen reader and Google seems to index the text OK so I guess it doesn't view it as a "black-hat" technique.

There is a flaw with this technique and that is that most browsers allow you to disable images. If you were to build a page where most of the text was replaced using the text-indent technique and someone did browse it with images turned off they would see an almost entirely blank page. Some people might consider this a moot point because after all who in the age of high speed internet access really disables image downloads? However, in my opinion there does seem to be something intuitively wrong with this technique. It just doesn't feel right to me having a load of text mysteriously floating somewhere off screen.

So, what's the alternative? Well, it seems that there are no perfect solutions to this problem. There are a number of different solutions that I've seen suggested. For example, if your image has a flat background and you can fit it in you can make the text small and hide it in the image. Then have a contrasting background color underneath so that it is visible with images turned off (http://mondaybynoon.com/2006/10/23/my-latest-take-on-image-replacement/). I've also seen an article (http://www.drunkenfist.com/304/2007/03/19/an-alernative-to-negative-text-indent-for-image-replacement-css/) that suggests using opacity in CSS to make the text transparent though this will only work in modern browsers and requires an additional element in your markup.

Another alternative that requires an additional element purely for presentational purposes is as follows:

<h1 id="hello-world">Hello World<span></span></h1>
#hello-world
{
position: relative;
width: 100px;
height: 25px;
overflow: hidden;
}
#hello-world span
{
display: block;
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 25px;
background: url(helloworld.gif) no-repeat;
}

The original explanation (I think) of this technique can be found here (http://levinalex.net/files/20030809/alternatefir.html). Again this doesn't feel right. Mainly because your markup is less semantic and your code become a lot more bloated when compared with the text-indent method. However this technique does work nicely if you do happen to have images switched off. Note: If you use a transparent gif then you'll be able to see the text because it's sitting underneath the image.

So which method should you use? I don't think there is a definitively right or a wrong answer because all techniques I have seen have some kind of drawback. Which method is right for you will depend on your target audience.

I've created a test page that demonstrates the techniques I have discussed in this article:

Examples of CSS Image replacement techniques

No comments:

SyntaxHighlighter