CSS Image Replacement Tutorial

CSS image replacement, or Fahrner Image Replacement (FIR) as the original method was called, is a cool and useful trick that you can do with CSS to spice up some of the text on your web pages. The basic premise is that we replace plain text in HTML with an image; doing this not only makes the text (potentially) look better but also doesn't carry the usual accessibility or search engine unfriendly consequences. I discovered recently that this technique wasn't as widely known as I had thought so I figure I'll do my bit for spreading another CSS technique to the masses.

I'll assume a bare minimum amount of knowledge here: you'll need to know how to use some basic HTML markup, including how to create a page, and at least know what CSS is.

To start off with, we need to create our HTML. The technique described here is best used for important text that you want to make sure is "fancy" and also text that doesn't change too often, as each change will require a change of the image we're using as a replacement. Headings are therefore ideal. In fact, the header for this very blog uses a variation of this technique. So, for the purposes of this example, let's have a heading of "My Page":

<h1>My Page</h1>

The <h1> tags signify that this is a top-level heading and therefore very important. Search engines like Google will often take this into account and weigh headings more than the rest of the text on your page. Presumably, this heading will be in a "header" area that I will represent with a <div>:

<div>
    <h1>My Page</h1>
</div>

The <div> doesn't do anything by itself, except make the whole thing function as a block. I should mention that you can place anything else in this header area that you'd like (except maybe another <h1>) and it won't affect what we're going to do. Since a raw <div> isn't unique in any way, we'll now add a CSS "hook" to it that will make it easy to style, and hopefully provide some semantic meaning for anyone who has to work with the HTML.

<div id="header">
    <h1>My Page</h1>
</div>

The id property of an HTML tag works by giving that tag a unique identification name (surprise surprise). Please remember that this name must be unique. If you want to use a heading that is going to be repeated a few times that you don't want to be unique then replace "id" with "class". If you're not familiar with CSS, id basically says "this thing is the one and only X" whereas a class says "this thing is a type of Y".

So, we now have all our HTML in place! Not much right? Well, you can already open that in a browser and take a look. You should see a large heading with the text My Page. When you're going through the rest of this tutorial, remember that what you have right now is what search engines "see", and what a screen reader would read out.

We're now going to start on our CSS. If you haven't used CSS before there are a few ways to add this in but in the interest of brevity I'll explain how to use a <style> tag. You use this tag inside the <head> tag of your HTML page and place all the CSS for that page inside it. I'll show this visually in a bit. To start our CSS we will need to reference the <h1> we created previously. To do this we use the following (including the afore mentioned <script> tag):

<script type="text/css">
#header h1 { }
</script>

The #header refers to the tag we placed the id="header" onto, in this case the <div> we used for the header area. The h1 following it means any <h1> tag that is inside a tag with id="header" on it. If we left the h1 one then that line would refer to the <div> instead. I also could have written the line as:

div#header h1 { }

This doesn't make any difference but I think the first way is easier to read, as well as having the ability to refer to whatever tag has an id of "header" – it could be a <td>, <label> or whatever. The braces after the h1 are what contains our CSS so let's put some in there:

#header h1 {
  background-image: url('/images/header.jpg');
  width: 300px;
  height: 100px;
}

The first part of the new code is a CSS property to change the background image for the tag (bet you didn't guess that huh?). Following the colon is the URL to wherever your image is. You should obviously change the image to whatever you want to use as a replacement. Following the background-image property are the width and height properties which set the width and height for the <h1> block – set these to the number of pixels in width and height that your background image is. If you view this in your browser you should see your replacement image showing up. Unfortunately the original text is still there so we'll get rid of this next:

#header h1 {
  background-image: url('/images/header.jpg');
  width: 300px;
  height: 100px;
  text-indent: -9000px;
  overflow: hidden;
}

The changes here simply indent the text 9000 pixels off to the left (hence the minus sign) and hides any overflow from the text so that it doesn't do weird things to our now clear <h1> block. The overflow property isn't actually needed but I like having it in there anyway.

If you look at this in a browser you should have a fully working image replacement for your heading – congratulations! As far as nifty techniques go, this one doesn't require a lot of code to achieve, which is one of the reasons why I like it so much. It's simple and effective.

I mentioned earlier that this blog uses a variation on this technique. To save you looking at the HTML source, I have placed the background image on enclosing <div>, rather than the <h1>. There was no real reason for this, except that I felt it best (or easiest) to incorporate the heading image directly into the header background image.

For the original article on CSS image replacement, and an alternative way (or, rather, the original way of doing it), read "Using Background-Image to Replace Text" on Stopdesign. The original technique probably shouldn't be used as it doesn't actually work in screen readers and thus invalidates one of the reasons for doing it in the first place!

Well, I hope you got something out of all this. If you have any questions or suggestions please leave a comment.

For the sake of completeness, the minimum amount of stuff you need for a basic page using this technique is to have the following in a HTML file (eg. page.html):

<html>
    <head>
        <title>My Page</title>
        <script type="text/css">
        #header h1 {
          background-image: url('/images/header.jpg');
          width: 300px;
          height: 100px;
          text-indent: -9000px;
          overflow: hidden;
        }
        </script>
    </head>
    <body>
        <div id="header">
          <h1>My Page</h1>
        </div>
    </body>
</html>