Fluid image replacement techniques

While you can find two dozen blog posts and articles about various image replacement techniques using Google, I couldn’t find any article that would help when you want the replacement to be fluid.

If the term “image replacement” is unknown to you, it basically means that we replace some content on a page – usually text – with an image.

I’m not a huge fan of using image replacements in the first place, but it’s often necessary to do so. One quite popular example is a logo. Logos – when used on a Web page – are usually images that have text inside them. If we want that text content to be visible to search engines, screen readers and text based browsers (Elinks, Lynx, ...) we need to use some kind of image replacement technique.

The most popular image replacement technique right now is probably this:

HTML:

<h1>Header</h1>

CSS:

h1 {
  background: url(image.jpg) no-repeat;
  text-indent: -9999px;
  overflow: hidden;
  width: 100px;
  height: 50px;
}

I think that the method described above is good if we just need to replace a logo, but what can we do when we want the replacement to be fluid and scale with the layout? Well, we could add a background-size CSS property which is supported in Firefox, Safari, Chrome, Opera, and IE9+ to make it a bit better:

CSS:

h1 {
  -webkit-background-size: 100% auto;
  -moz-background-size: 100% auto;
  background-size: 100% auto;
}

Now by changing the width & height of the header between different Media Query trigger points we could change the size of the replacement image. That doesn’t help much though if we want/need the replacement to be completely fluid.

Back to the past

Because of the non-fluid nature of the last example, I’m suggesting an alternative method to “replace” the text, which, I think, is actually the way image replacement was done before all these CSS methods about 10 years ago (...now added with few improvements):

HTML:

<h1>
  <img src="image.jpg" alt="Header" />
</h1>

CSS:

h1 img {
  width: 100%;
  height: inherit;
  -ms-interpolation-mode: bicubic;
}

@media print {
  h1 img {
    display: none;
  }
  h1:after {
    content: "Header";
  }
}

This method also hides the image when you print the page and replaces it with the text from the image. This is something that’s really useful if the text inside the image is white as on my own home page. You might also want to add a max-width for the H1 or the IMG to avoid the image scaling too much.

I’m not a SEO expert so I don’t know how this particular technique performs against H1 with real text content, but at least screen readers, text browsers and search engines see the text now (I tested if the ALT description used in this kind of example shows up in Google results by searching for my own site and the words inside ALT description. The text did, in fact, show up there).

Putting more thought into this

I started wondering if it's possible to automatically get the content of the ALT description for printing, so that we wouldn't have to write all the texts inside the stylesheet. This is what I came up with:

CSS:

@media print {
  h1 img {
    display: none;
  }
  h1 img:after {
    content: attr(alt);
  }
}

That should work in all major browsers + now we don't have to worry so much about our stylesheet anymore.

Usage of an H1 tag

I’d say that you shouldn’t probably wrap a logo inside an H1 tag. The Example uses H1 just because the main header on this site uses an image replacement and this blog post kind of grew up from that particular use case. I’m using image replacement because I wanted to make the header look identical across multiple platforms/devices, also the ones that don’t have support for @font-face.

Further reading

CSS-Tricks has an article about similar method (non-fluid), called Rethinking CSS Image Replacement, but I think that the “remaining problems” described there are incorrect. This method does show the alternative text when someone is browsing CSS turned on and images turned off, Webkit being the only exception. At least this was the case when I tested it.

There are few caveats also: If you are worried about how Internet Explorer (prior to version IE8) and older mobile devices will render the image when it’s scaled down, then I suggest you to read Ethan Marcotte’s article called Fluid images. There's a small script to fix the problem with Explorer.

At this stage we (and I) should also probably think about how to implement responsive images and not just serve one big image for all screen sizes. Jeremy Keith has an interesting post titled Responsible responsive images about that subject.

← Blog