Nine Techniques for CSS Image Replacement

Chris Coyier //

CSS image replacement is a technique of replacing a text element (usually a header tag) with an image. An example of this would be including a logo on a page. You may want to use a <h1> tag and text for this for the accessibility and SEO benefits, but ideally you'd like to show your logo, not text.

Update (March 14, 2012). I've created a new page that now covers more image replacement techniques, including the more recent Scott Kellum Method and the HTML5BP Method. I'm calling it the CSS Image Replacement Museum.

Note that some of these techniques are very old. Web design in the early 2000's was a lot different than it is now, but there was still much thought being put into accessibility. Because of that, most of these techniques still hold up today. It is still very interesting to see all the thought and problem solving that was put into this. Also note that I tested all these FF2, Opera 9, Safari 3, and IE 6 and they all behaved identically (hard to believe, I know).

The report card consists of five major categories:

  • CSS ON / Images ON
    Represents browsers in their normal states. All techniques should pass this test, since that's the whole point.
  • CSS ON / Images OFF
    Represents browsing with regular stylesheets applied but images turned off. This is rare but a possibility (folks with bandwidth concerns...) This is the most difficult test. Since most of these techniques go to various lengths to hide text, when the images are turned off that means that nothing is displayed which ain't good. Displaying text only here is considered a pass.
  • CSS OFF / Images ON
    Represents browsing with no stylesheets being applied. Most techniques default to regular web text here which isn't exactly a fail, but since images may still be turned on, I don't consider it a pass either.
  • CSS OFF / Images OFF
    Represents browsing with both images turned off and no stylesheets applied. Defaulting to text here is considered a pass.
  • Extra Unnecessary Markup
    Having to add markup for the sole purpose of image replacement is not ideal. Does not achieve true separation from content and design.

Technique #1

<h1 id="technique-one">
  <span>CSS-Tricks</span>
</h1>
h1#technique-one {
  width: 250px;
  height: 25px;
  background-image: url(logo.gif);
}
h1#technique-one span {
  display: none;
}

report-card-1.png

More information: This technique is referred to as FIR or "Fahrner Image Replacement". Much has been written about this including an A List Apart article about it's problems with accessibility as well as an article from David Shea defending it. The premise here is to use a span to wrap the text inside the header and use that span to hide the text. It works, but using display: none will hide the text from screen readers (and presumably search bots, not good).

Technique #2

<h1 class="technique-two">
  CSS-Tricks
</h1>
h1.technique-two {
  width: 2350px; height: 75px;
  background: url("images/header-image.jpg") top right;
  margin: 0 0 0 -2000px;
}

report-card-2.png

More information: Radu Darvas is credited with this technique. Basically this technique creates a giant box that goes way off the screen to the left. The text, being left-justified, cannot be seen. The image is placed in the top left of this box. It works, but it has the common problem of failing with CSS ON / Images OFF. I can also see this giant box thing being a problem in more complex layouts, besides being just generally less efficient than some other techniques.

Technique #3

<h1 class="technique-three">
  CSS-Tricks
</h1>
h1.technique-three {
  width: 350px; 
  height: 75px;
  background: url("images/header-image.jpg");
  text-indent: -9999px;
}

report-card-3.png

More information: This technique is credited to Mike Rundle and referred to as the Phark Method. This is probably the most widely used technique today. At the time of this writing, it is certainly the one I use most often. There is even a T-Shirt based on this one (2nd up from the bottom. The premise is deliciously simple: replace block with background image, kick text off page with indent. It's effective and keeps screen readers happy. It only fails the elusive CSS ON / Images OFF issue. A variation on this technique is to use negative letter spacing instead, which purports to resolve problems with triggering huge unwanted scrollbars in some browsers.

Technique #4

<h1 class="technique-four">
  <a href="#">
    <img src="images/header-image.jpg" alt="CSS-Tricks" />
  </a>
</h1>
h1.technique-four {
	width: 350px; height: 75px;
	background: url("images/header-image.jpg");
	text-indent: -9999px;
}

report-card-4.png

More information: I'm not sure the origin of this technique, but it's basically an extension of the Phark technique. Instead of bumping text off the screen you are bumping an image off the screen. This has the distinct advantage of still showing an image when CSS is OFF and images are ON, and also has ALT text for 508 compliance. This technique still fails with CSS ON / Images OFF. I give credit to Volkan Görgülü for pointing out this is the technique that Smashing Magazine is using in their header. One concern over this technique is whether or not it is effective SEO, specifically, if ALT text is just as good as regular web text. An extension of this technique would be to include regular web text inside the anchor link as well. Both the text and the image would get bumped off the page with the text-indent and it would aliveate the SEO concerns, but then you'd get "double text" with both images OFF and CSS OFF.

Technique #5

<h1 class="technique-five">
  <img src="images/blank.gif" alt="CSS-Tricks" />
  <span>CSS-Tricks</span>
</h1>
h1.technique-five {
	width: 350px; height: 75px;
	background: url("images/header-image.jpg");
	}
	h1.technique-five span {
		display: none;
	}

report-card-51.png

More information: Radu Darvas is also credited with this technique. By including a single-pixel transparent GIF image to the markup, you can restore ALT text with images turned off. This allows text to be displayed with CSS ON / Images OFF (!). Very effective, but adding the shim GIF is quite the blow to semantics. Also, with both CSS and Images OFF you get "double text", meaning both the alt text and the regular header text.

Technique #6

<h1 class="technique-six">
  CSS-Tricks
</h1>
h1.technique-six {
	width: 350px;
	padding: 75px 0 0 0;
	height: 0;
	background: url("images/header-image.jpg") no-repeat;
	overflow: hidden;
}

More information: This technique is credited to simultaneous discovery by Seamus Leahy and Stuart Langridge. This technique creates a box which will render with a height generated solely by top padding. By setting overflow to hidden, text will automatically be hidden but the box will be properly sized for a background image. This is accessibility-friendly and fairly effective, but fails in the CSS OFF / Images ON test as well as requires a box model hack for older versions of IE.

Technique #7

<h1 class="technique-seven">
	<span>CSS-Tricks</span>
</h1>
h1.technique-seven {
	width: 350px; height: 75px;
	background: url("images/header-image.jpg") no-repeat;
	}
	h1.technique-seven span {
		display: block;
		width: 0;
		height: 0;
		overflow: hidden;
	}

report-card-7.png

More information: Credited to Leon Dwyer. This technique is able to hide the text by putting it inside a box 0px wide and 0px tall with hidden overflow. Because it doesn't use the display attribute to hide the text, it's safe for screen readers.

Technique #8

<h1 class="technique-eight">
  <span></span>CSS-Tricks
</h1>
h1.technique-eight {
	width: 350px; height: 75px;
	position: relative;
	}
	h1.technique-eight span {
		background: url("images/header-image.jpg");
		position: absolute;
		width: 100%;
		height: 100%;
	}

report-card-8.png

More information: This technique is credited to Levin Alexander. In this technique, instead of pushing the text off the page or otherwise hiding it, the background image just sits on top of the text. This is the only other technique besides #5 which passes the CSS ON / Images OFF test. One problem with this technique is that if your background image uses transparency, the text will show through. Also, while not included in the original writeup of this technique, I would suggest hiding the overflow so that if the text size is bumped up large enough that it breaks out of the box it won't show.

Technique #9

<h1 class="technique-nine">
  CSS-Tricks
</h1>
h1.technique-nine {
  width: 350px; height: 75px;
  background: url("images/header-image.jpg") no-repeat;
  font-size: 1px;
  color: white;
}

report-card-9.png

More information: This technique is credited to Russ Weakley. With this technique, simply setting the text to an ultra-tiny 1px size and matching it's color to the background color of the image, you don't even need to hide it. While this technique makes a lot of sense accessibility wise, it has it's own problems. Like most of the others, it doesn't work with CSS ON / Images OFF. Even at the 1px size, the text is still visible, so this will only work on flat color backgrounds where it can blend in perfectly. I also have my suspicions that there may be some SEO penalties for this, both for the very small font-size and for matching background-color and color.

Even more information...

  • As usual, there is also a javascript solution.
  • There is a technique for doing this with inline-blocks instead of blocks.
  • If the only reason you are using this is to change the font, you'd be better off using @font-face.
  • Google Webmaster Tools has an article about this which doesn't specifically cover image replacement but reading between the lines, it seems like a reasonable amount of usage of this technique will have no negatives.