iIR: img Image Replacement

By Aaron Gustafson

There’s been lots of discussion with regard to best practices when replacing text with an image using CSS, but very little discussion of replacing one image with another in media-specific instances. Ross Howard explored the concept in his ALA article on hi-res images for print, but beyond that it isn’t a topic that has come up much.

While working on a project for a purveyor of fine teas, I decided to experiment with some image replacement of my own. The design called for a header graphic with a ripple effect, upon which the logo and some navigational elements were placed:

A sample from the design I needed to recreate

I wanted to accomplish this with as little markup as possible and here’s what I came up with:

<h1 id="branding">
  <img src="/images/logo-print.jpg" alt="Twinings of London" />
</h1>

This markup sets up the print-friendly logo (logo-print.jpg) as the default image and as the most important heading on the page (which, as this example is from the homepage, it is). Consider it a bit of a nod to Dan Cederholm’s bulletprof logos too. This is also the image we will be replacing using what I call iIR (img Image Replacement).

In the past, I would have added extra markup to create the header (perhaps a div) and simply moved the image out of view by applying the Phark method to the h1 (which works well on imgs set to display: inline). The problem with this technique was that you lose the alt text if images are turned off but CSS is on. Also, in an effort to keep the markup clean, I was already planning to use the h1 to set up the header graphic:

#branding {
  background: #ad0910 url(/images/layout/header.jpg) top left no-repeat;
  margin: 0;
  height: 99px;
}

I was determined to add no additional markup, so I decided to explore other options. The Leahy/Langridge Method came to mind. I wasn’t sure how it would work on a replaced element like img, but decided to give it a shot. I started with the print-friendly logo positioned where I wanted it (borders have been added to outline the size of the img element):

#branding img {
  position: absolute;
  top: 3px;
  left: 10px;
}
A screenshot of the print-friendly image positioned over the background (borders added for emphasis)

The next step was to set the img to display: block, apply the screen version of the logo as a background image and pad the top of the img to push the print version down to reveal the screen version (width is also set for good measure):

#branding img {
  background: url(/images/logo.png) top left no-repeat;
  display: block;
  padding-top: 93px;
  width: 129px;
  position: absolute;
  top: 3px;
  left: 10px;
}
A screenshot of the print-friendly image pushed down by padding-top to reveal the background image of the screen logo (borders added for emphasis)

Finally, I cropped out the print version by setting the height of the img to 0:

#branding img {
  background: url(/images/logo.png) top left no-repeat;
  display: block;
  padding-top: 93px;
  height: 0;
  width: 129px;
  position: absolute;
  top: 3px;
  left: 10px;
}
A screenshot of the print-friendly image cropped out of view to show only the screen logo (borders added for emphasis, print-image opacity reduced to imply it not being seen)

Much to my surprise, this technique is widely supported in all modern browsers, including IE6. And, the best part is that the alt text is still available with CSS on and images turned off:

A screenshot of the page with CSS on, but images turned off

I think the concept of iIR can be explored a lot more in-depth, possibly as an alternative to Russ’ approach to using hi-res, print-friendly images on our sites. The bonus of this approach (as opposed to Russ’) is that we don’t have to resort to adding extra markup to do it.

Here’s the final version, sans borders:

A screenshot of the final layout.

Questions/Comments

I will be happy to take any questions or comments about this article in it’s associated blog entry.