A History of CSS Image Replacement

Baljeet Rathi
Share

Image replacement in CSS has had a wide and varied history. In this modern age, if you are still looking to do so, there are many image replacement techniques that still work today. It is important to note that some of these could in fact be penalized by Google soon (if not already), so use sparingly. However, you never know when a CMS or project will force you to need to get out the image replacement kit! Here is that historical kit, in what might be the last image replacement technique list you’ll need before the web moves beyond this entirely.

Image replacement magician

Artwork by SitePoint/Natalia Balska

Using Negative Text-indent — The Phark Method

This is the most common technique that most web developers have used at one point or another. The idea here is to move the text far outside the browser window by setting a large negative text-indent:

.replace-indent {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
  text-indent: -9999px;
}

Here is a CodePen demo showing how the heading looks with the text hidden using text-indent:

See the Pen Image replacement indenting by SitePoint (@SitePoint) on CodePen.

The text is still accessible by screen readers using this method. However, this solution won’t work when the text is right aligned. The browser also needs to render a very large box for our header due to the text-indent value which can be problematic on very old devices.

The Scott Kellum Method

Instead of setting a large negative text-indent, you can set it to 100%. This way the browser won’t need to create a large box and the performance will improve. You don’t need any extra markup to use this method. Here is the CSS that you need:

.replace-scott {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

Setting overflow to hidden hides the text and whitespace: nowrap keeps it from moving onto the next line. The text will still be read by screen readers in this method. Here is a demo of this technique:

See the Pen Image Replacement – Scott Kellum Technique by SitePoint (@SitePoint) on CodePen.

Using Margin — Radu Darvas Technique

This technique also forces the text outside of the browser window but uses margins to do so. The idea here is to apply very large negative left margin and give your header a correspondingly large width.

.replace-margin {
  width: 2264px;
  height: 106px;
  background: url("assets/logo.png") top right no-repeat;
  margin: 0 0 0 -2000px;
}

Just like the previous case, our logo is used as a background image for the heading. Here is a demo to show how this technique works, first without the margin and then with the margin applied:

See the Pen Image Replacement – Margin Technique by SitePoint (@SitePoint) on CodePen.

If you keep scrolling to the right you will eventually see the background for first heading. In reality, you won’t have to worry about the scrollbar because the large negative margin compensates for the width (as you can see with the second heading). Keep in mind that this method is not as efficient for the browser to perform because the browser has to draw a really large box.

Using Padding — The Langridge Method

This time we push the text outside of our header using the padding-top property. The property is to be set to a value that is equal to the height of our logo. However, this alone is not enough and we also have to use overflow: hidden to hide the text.

.replace-padding {
  width: 264px;
  height: 0;
  background: url("assets/logo.png");
  padding: 106px 0 0 0;
  overflow: hidden;
}

Compared to the previous two methods, this property does a much better job performance wise. It also offers the same level of accessibility as the previous two methods. Below is a demo of this technique, the first heading does not have the padding background, while the second one does:

See the Pen Image Replacement – Padding Technique by SitePoint (@SitePoint) on CodePen.

Using Small font-size — The Lindsay Method

Another way to hide text is make it very small and set its color to the background of your logo. This works without affecting accessibility but you might face SEO penalties because of the tiny font size and camouflaged color.

.replace-font {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
  font-size: 1px;
  color: white;
}

Here is a demo for this method, the first image without the font-size fix and the second one with it in action:

See the Pen Image Replacement – font-size Technique by SitePoint (@SitePoint) on CodePen.

You will still face problems if your logo does not have a flat background color to allow perfect blending. In that case, you can set the color to transparent.

Using Display — Fahrner Image Replacement

Unlike other methods, this one requires you to add some extra markup. The idea here is to wrap your text in a <span> element and set its display property to none. The markup in this case would be:

<h1 class="replace-display">
  <span>SitePoint</span>
</h1>

The CSS would be:

.replace-display {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
}

.replace-display span{
  display: none;
}

Here is a demo with the display of our <span> element set to none:

See the Pen Image Replacement – Display Technique by SitePoint (@SitePoint) on CodePen.

This method, while easy to implement, results in poor accessibility. This is because elements with display set to none are ignored by screen readers. The exact same issue occurs with visibility set to hidden so you can’t use that one either. What you can do is set opacity to 0. This will hide the element while still keeping it accessible to screen readers.

Using Overflow — The Leon Dwyer Method

We have already used the overflow property to hide our text after adding some padding. This time we will use just the overflow property to hide the element completely. Using this technique requires that you wrap your text in a <span> element just like the previous method. Our CSS this time around looks like so:

.replace-overflow {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
}

.replace-overflow span {
  display: block;
  width: 0;
  height: 0;
  overflow: hidden;
}

We set the width and height of our span element to zero. This forces the text inside the element to move out of its box. The text is then hidden by the overflow: hidden property. Here is a CodePen demo illustrating this technique:

See the Pen Image Replacement – Overflow Technique by SitePoint (@SitePoint) on CodePen.

The text is still accessible to screen readers. Hence, there are no accessibility issues.

Using Absolute Positioning — The Levin Technique

This method also requires an additional <span> element to work. However, the <span> element is not wrapped around the text but used to position our image. Here is the markup for this method:

<h1 class="replace-position">
  <span></span>SitePoint
</h1>

Here is the CSS:

.replace-position {
  width: 264px;
  height: 106px;
  position: relative;
}

.replace-position span {
  background: url("assets/logo.png");
  width: 100%;
  height: 100%;
  position: absolute;
}

The demo for image replacement with absolute positioning is visible below:

See the Pen Image Replacement – Absolute Positioning Technique by SitePoint (@SitePoint) on CodePen.

Notice that the width and height are set to 100% to completely cover our header element. The only problem with this technique is that the images you use must be completely opaque. If that’s not the case then users will be able to see the text through your image.

Using a Bogus Image — Radu Darvas Shim

This method also requires a bogus image in addition to our usual <span> element to work properly. The image is a 1×1 pixel transparent GIF. Its main purpose is to show users the alt text if images are turned off. Here is the markup:

<h1 class="replace-image-span">
  <img src="assets/transparent.gif" alt="SitePoint" />
  <span>SitePoint</span>
</h1>

This is the CSS that you need to apply:

.replace-image-span {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
}

.replace-image-span span{
  display: none;
}

The demo below should make it clear how this method works:

See the Pen Image Replacement – Bogus Image Technique by SitePoint (@SitePoint) on CodePen.

Even though the actual text is hidden, screen readers will still be able to read the alt tag. So, this method does not create any accessibility issues. The only problem here is that the <img> tag is non-semantic and bogus in this case. Moreover, you will see the text two times if both the CSS as well as the images are turned off.

Using Actual Image — Phark Method with Inline Image

This time, we will use an actual image for image replacement. The image has alt text that will be shown when images are turned off. Here is the markup:

<h1 class="replace-image-link">
  <img src="assets/logo.png" alt="SitePoint" />
</h1>

The following CSS does the actual replacement:

.replace-image-link {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
  text-indent: -9999px;
}

The demo below illustrates how this technique works:

See the Pen Image Replacement – Actual Image Technique by SitePoint (@SitePoint) on CodePen.

The image you will see now is not from the <img> tag but from the background property. Besides the issue with large negative text-indent that we discussed earlier, this technique does not seem to be good for SEO. One advantage that this technique offers over others is that the image will still be visible with CSS turned off and images kept on but one questions why you wouldn’t just keep the image there on its own…

Using Clip-path

The clip-path property hides everything that is outside the path specified by you. We can use it to clip our text and hide it. The text will still be accessible to screen readers but would be hidden visually. Here is the markup:

<h1 class="replace-clip-path">
  <span>SitePoint</span>
</h1>

This is the CSS that you need to apply:

.replace-clip-path {
  width: 264px;
  height: 106px;
  background: url("assets/logo.png");
}

.replace-clip-path span{
  clip-path: polygon(0px 0px, 0px 0px, 0px 0px, 0px 0px);
}

You can change the values of clip-path to see how the text is being clipped:

See the Pen Image Replacement – clip-path Technique by SitePoint (@SitePoint) on CodePen.

The only problem with this technique is that browser support is not good enough just yet. SitePoint recently published an article on the clip-path property which discusses the property in much more detail. By the time browser support is ready for this, it’s likely to be unnecessary in most situations as image replacement techniques become redundant.

Using Pseudo Element — Nash Image Replacement

This technique uses a pseudo element to push the text aside. Here is the markup:

<h1 class="replace-pseudo">
  SitePoint
</h1>

The following CSS makes this technique work:

.replace-pseudo {
  width: 264px;
  height: 106px;
  overflow: hidden;
}

.replace-pseudo:before{
  content: url("assets/logo.png");
}

Here is the demo to show this technique in action:

See the Pen Image Replacement – Psuedo Element Technique by SitePoint (@SitePoint) on CodePen.

The pseudo element pushes the text aside. The text then overflows and is hidden by using the overflow: hidden property. One issue with this technique is that it only works with Internet Explorer 8 and above.

Conclusion

Each of the techniques I discussed above has its own pros and cons. In general, these aren’t likely to be good for SEO in the near future and if you can avoid using them entirely — now is the time to move beyond these! In an upcoming article here at SitePoint, we will be looking at how the industry is moving beyond these and what current best practice is today. If you have any other techniques that you would like to reminisce over or if you have something else to add regarding the techniques we discussed, please comment below.

Update from PatCat (30/06/2016): The article originally stated that using images in site headers would negatively affect SEO and accessibility. This isn’t true. In fact, the opposite could be true with Google’s potential penalizations for image replacement. I’ve since corrected the article, thank you to the keen eyes of commenters for bringing this to my attention!