659-image-replacement

Goodbye -9999px: A New CSS Image Replacement Technique

By | | CSS | HTML | JavaScript

The -9999px image replacement technique has been popular for the best part of a decade. To replace a text element with an image, you use the following code:


<h1>This Text is Replaced</h1>
<style>
h1
{
	background: url("myimage") 0 0 no-repeat;
	text-indent: -9999px;
}
</style>

The element’s background is displayed and it’s text is moved off-screen so it doesn’t get in the way. Simple and effective. It was often adopted to show graphical titles — that’s rarely necessary now we have webfonts, but you’ll still find it used all over the web.

Until now.

A new technique has been discovered by Scott Kellum and promoted at Zeldman.com:


#replace
{
	text-indent: 100%;
	white-space: nowrap;
	overflow: hidden;
}

The code indents the text beyond the width of its container but it won’t wrap and the overflow is hidden.

While it’s a little longer and more difficult to remember, performance can be improved because the browser’s no longer drawing a 9,999px box behind the scenes. It will also prevent the weird left-extended outlines you’ll see around links using hidden text.

I haven’t been able to discover any downsides — only than I wish I’d discovered it first. Have you adopted the technique? Have you experienced any issues?

The Ultimate JavaScript Bundle: 2 books + 1 course

Buy now $39 Normally $117 - save 66%

Or get access to all SitePoint's Premium Content with a Learnable membership

Craig Buckler

Craig is a Director of OptimalWorks, a UK consultancy dedicated to building award-winning websites implementing standards, accessibility, SEO, and best-practice techniques.

More Posts - Website

{ 56 comments }

Rick Noel May 9, 2012 at 7:11 pm

Hi Craig, nice technique. Performance is key especially with smartphone browsers with limited resources rendering more and more content these days. Does anyone know if any of the techniques discussed in this thread have known negative SEO impacts, especially for Google, Bing? I know that the search engines expect to crawl/index what users to see these hidden text replacement techniques could be used in manipulative ways. The most obvious examples included keyword stuffing with font color the same as the background? Are any of the techniques discussed here less likely to trigger a penalty from Google or Bing? Thanks for sharing.

Keiron Lowe May 3, 2012 at 5:45 am

The only downside I have found so far is when using screen readers. I’m not sure if it’s a Voiceover only issue but when the element using this technique has focus, the text is visible.

pkrey April 17, 2012 at 9:14 am

Does anyone use this method?

h1
{
background: url(“myimage”) 0 0 no-repeat;
margin:0;
padding:0;
height:100px;
width:150px;
}
h1 strong
{
display:none;
}

My Company

You could use a , or whatever you want instead of the .
Any down side to display:none over those other methods?

Anonymous April 20, 2012 at 12:47 am

Using display:none is very very bad for SEO. Google doesn’t crawl elements set to display none as an older seo technique (cheat?) was to keyword stuff a div, then set it to display:none.

ralph.m April 14, 2012 at 8:52 pm
Werner Beroux April 13, 2012 at 5:49 am

All I can see is a lack of consensus about which is simpler and which is most clean or favorable.

soda lime April 13, 2012 at 3:35 am

Thanks for the knowledge i will try it sure…….

Nicholas Johnson April 13, 2012 at 3:16 am

Image replacement has never been a good technique. A site should work with images off. Image replacement removes the alt text image accessibility fallback.

Use real text in a font for titles. If you must use an image, use a real image with alt text. It’s more correct, it degrades better, and you will not suffer any SEO consequences.

Gabriel de Kadt April 13, 2012 at 2:07 am

I’m with Joseph Mansfield (and yer man Matt Cutts at Google) – use the alt tag. If your design requires headings to be rendered as an image – wrap the image the appropriate heading tag. Usual best practices still apply for SEO… keep it simple.

Peter April 13, 2012 at 1:39 am

This technique looks promising – thanks a lot.
Please forgive a very naive question: why don’t we just use ‘display:none’ to hide the title text? Or is this a bad thing from an SEO perspective?

Greg Kraus April 20, 2012 at 6:51 am

Screen readers won’t read the text if you use display:none or visibility:hidden

Trevor Geene April 13, 2012 at 12:03 am

My only question is about SEO. Is it better to do this or use an image with an alt tag on it, and does google frown on this like “text-indent:-9999px”?

AndyW April 13, 2012 at 3:01 am

Google doesn’t ‘frown’ on text replacement, unless it’s used for nefarious purposes and you get reported by someone. I’ve used text-indent: -9999px on dozens of sites and never suffered the wrath of Google for it.

Marc Haunschild April 12, 2012 at 9:36 pm

It is just lame to use pictures instead of text. And of course, if you do so, then use an img with alt – background-images will disappear, when users define their own background color.
Of course there are more accessibility problems, that we all know, I hope.

Ray mosley April 12, 2012 at 2:39 pm

I think the drawback is if images are off or missing, no text underneath. However using an absolutely positioned span in the element (such as a tag or h1) and giving the background to that span will make it more accessible approach. You should also not remove outline.

Joseph Mansfield April 12, 2012 at 1:19 pm

The proper way to deal with this is to use the alt attribute:

See the HTML5 standard (http://www.w3.org/TR/html5/the-img-element.html#text-that-has-been-rendered-to-a-graphic-for-typographical-effect) and the Google Webmaster youtube channel (http://www.youtube.com/watch?v=fBLvn_WkDJ4).

Pawel April 12, 2012 at 11:24 am

I like this alternative. I’ve always avoided this “-9999px” so called “technique”, bacause it really is lame – so bizarre and awkward. It’s like wanting to make a layer transparent in Photoshop by moving it off screen instead of setting the transparency to zero. Only a complete noob would do that.

Andy April 12, 2012 at 5:07 am

How exactly is this a new technique when it’s pretty much what we’ve been doing for years already?

The overflow: hidden rule will prevent any text from being rendered off-screen regardless if you indent to the left or right, and it will also prevent the outline from stretching outside of the box.

Nothing to see here.

Ang April 13, 2012 at 2:15 am

Exactly, nothing new here except white-space: nowrap; which is only needed because of smaller indent and only in case of larger text blocks… I use text-indent: -99em; and overflow: hidden; only.

Eric Paré April 11, 2012 at 2:03 pm

Very nice alternative for the top logo of websites ! Thanks a lot.

Iain April 11, 2012 at 1:41 pm

“It will also prevent the weird left-extended outlines you’ll see around links using hidden text.”

You can avoid this with the -9999px method as well, just add ‘outline: none;’ to the elements styles.

Alexei April 11, 2012 at 9:59 am

Downsides: Basically SEO. Although Google Panda changed all SEO ideas, its still a SEO best practice to avoid transparent texts, fonts with zero sizes, fonts with the same color as the background (with no sibling with different color) and overflow:hidden elements, specially top elements like H1

I avoid using all these techniques.

Antonin Januska April 12, 2012 at 12:19 pm

That’s something I’ve wondered about before but Google doesn’t mind things like that anymore. Why? Because it’s crucial to UX, design, and development. Does text that fades in/out get read? Yes, yes it does, even if it does have an opacity of 0. It’s the same as tabbed information, slides, sliders, and all other interactive elements (usually interactive via javascript).
Just my two cents :)

Richard Morton April 11, 2012 at 6:32 am

if -9999px causes a performance problem, then surely -999px would reduce that significantly and probably be enough for most situations.

Antonin Januska April 12, 2012 at 12:20 pm

not nearly enough. My designs start with a 1024px grid. I view sites on a 1600px wide monitor (and sometimes larger). The -999px may not hide it at all! :)

Richard Morton April 13, 2012 at 12:55 am

But it only matters if the text you are trying to hide is wider than the negative offset. In other words in my example so long as the text is less than 999px wide it doesn’t matter if your monitor is 1600px wide or 5000px wide it still won’t be shown.

Ang April 13, 2012 at 2:10 am

Actually, it would, just use overflow: hidden; it’s the main thing that makes the difference. And it’s nothing new, been using and seeing it being used for ages.

Shiva April 11, 2012 at 4:31 am

Has anyone tested it on IE6 ?

Gabe April 12, 2012 at 3:49 pm

LOL IE6

Df April 12, 2012 at 8:36 pm

Unfortunately some of us who are not script kiddies still have to support IE6….

Alastair Moore April 12, 2012 at 7:15 pm

What is this IE6 you speak of?

Dylan April 17, 2012 at 10:28 am

I disagree, Df, you choose to support IE6… this isn’t a demand.

Even IE itself is trying to kill off use of 6. Urge your clients to upgrade. I’m willing to bed that you don’t code with Opera in mind, so what makes IE6 any different? Add a banner saying “we noticed your browser is out of date, please update”, and if they don’t… Then too bad. They get bad browsing.

deathshadow April 10, 2012 at 11:24 pm

Given that NONE of the methods presented actually WORK as a image replacement technique, since there’s no text CSS on images off, I’m not sure what would posses someone to advocate this as a method that should actually be used on pages. -9999em has been rubbish from the day it was introduced… pushing it the other direction isn’t doing us any good either…

… at least not compared to an APo sandbag tag or :before element.

Literally, be it text-indent:-9999em or text-indent:100% with overflow, you are missing one of the reasons to even be doing image replacement in the first place!

DBosch April 12, 2012 at 11:12 am

Before proclaiming something as rubbish you might want to ask around why.
The methods are used for SEO purposes. all CMS and Blog software use H tags for the title which is crawled and evaluated by google bot for ranking your site. Designers who don’t want the text based title for their website but rather have well designed logo want to maintain proper linkage with google and other crawlers and bots so they hide text instead of deleting it and replacing it with an image.

You’re welcome

Alastair Moore April 12, 2012 at 7:28 pm

I think you’re missing the point of what deathshadow was trying to make (in a rather aggressive tone). Which is that these methods don’t work if a user is browsing a site with CSS turned on and images turned off. It would result in no text being visible at all.

Now, I’m not sure who browses the internet with this configuration but I’m guessing there’s a tiny minority. I suppose it all comes down to targeting your audience.

Our clients and users are media (image and video) consumers and so I think it would be fair to say none of them browse our sites with CSS on and images off.

Nicholas Johnson April 13, 2012 at 8:25 am

Google doesn’t seem to mind crawling alt text in an h1. There are plenty of people who’ll tell you that it does, but in my experience it makes zero difference.

I routinely rank well for h1 keywords in alt text.

deathshadow April 14, 2012 at 12:19 am

As Alastair said, you completely missed the point. I know what image replacement is, I use it all the time; but it should NOT be breaking images off content if it’s a true image replacement method.

People on narrow bandwidth like our friends in Canada with their newly metered connections, people in places like northern NH, western ME, the Dakota’s, etc. where broadband is a pipedream will often turn images off so they can actually use a website. -999em or this method give those people a blank page. It’s a broken methodology for what should likely be handled with generated content (:before) or a sandbag element absolute positioned OVER the text.

Since then images off CSS on it’s still a useful page instead of a giant blank space of nothing.

Well coded pages should be able to gracefully degrade — scripting off, images off, css off, or any mix-match combination.

Brian Temecula April 10, 2012 at 9:28 pm

I just put the image and text in a fixed size div with overflow:none and let the image push the text out. When doing this, the text falls back into position if images are turned off.

deathshadow April 14, 2012 at 12:20 am

If you mean using an IMG tag, that would be unpredictable cross browser, and misses the point of putting presentational images where they belong, in the CSS not the markup.

I figure you have to mean using IMG since what you said wouldn’t work otherwise.

J.F. Herrrra April 10, 2012 at 4:13 pm

I’ ve used it and have not found any problems.

samanime April 10, 2012 at 3:07 pm

The only downside I could see is if you needed something other than overflow: hidden on the element for some reason. =p

Mike Birch April 10, 2012 at 2:24 pm

I’m using an image replacement technique which has been added to HTML5 Boilerplate recently:

http://nicolasgallagher.com/another-css-image-replacement-technique/

“The new technique avoids various problems with any text-indent method, including the one proposed by Scott Kellum to avoid iPad 1 performance problems related to large negative text indents.”

Joe Zim April 10, 2012 at 10:15 pm

So many techniques, so hard to choose. I tend to just skip the image replacement and use other CSS to make the text look good. Obviously it can’t look as good as Photoshop will make it look, but it’s good enough in the modern browsers.

Mike Earley April 10, 2012 at 1:43 pm

I haven’t tried it yet, I’ll have to check it out. However, I’m not fond of techniques like this that are using the specified rules, only because there is potential to impact other parts of the page (small but there).

I’ve had great success with: http://nicolasgallagher.com/another-css-image-replacement-technique/

It works perfectly on all browsers so far, and unlike the technique above, shouldn’t impact any other elements on page, because it does not indent, manipulate overflow, etc.

.ir {
font: 0/0 a;
text-shadow: none;
color: transparent;
}

hua April 10, 2012 at 1:28 pm

Nice, I tested this imediately and works fine. For me, it’s nicer and more logical. While I’m using text replacing a lot, I certainly will use this in my future projects. Thanks for publishing.

Luiz Marques April 10, 2012 at 12:43 pm

Seems nice. I had no idea that the -9999px method had such a performance problem!

Larry Struthers April 12, 2012 at 1:07 pm

It doesn’t. Browsers don’t actually render these items.

Alex Thomas April 10, 2012 at 12:28 pm

Very interesting, il try this in any future development. Be interesting to see just how much quicker it is.

Francis Boudreau April 10, 2012 at 12:17 pm

Already adopted and it works like a charm :)

Richard Razo April 10, 2012 at 12:10 pm

With the high rez retina revolution plus the varying screen size environment I don’t know if this is worth discovering anymore.

Richard Razo April 10, 2012 at 12:12 pm

If you could create a tutorial to make this a viable solution for responsive websites, and high rez retina & connection speed variables I am interested to learn. Of course a ton of code wouldn’t be ideal since page load time is a factor too.

Daniel Shamburger April 10, 2012 at 11:17 am

Nice disovery! I use text-indent: -9999px; all the time to replace title text with a graphic logo in WordPress, so I’ll have to try this.

Michał Czernow April 10, 2012 at 11:13 am

Very elegant. I noramlly use something different:

.element {
overflow: hidden;
height: 1px;
padding-top: 149px; /* assuming that target height mus be 150px */
line-height: 99em;
}

Jacob Pitassi April 10, 2012 at 11:07 am

As someone who is against the whole -9999px technique, I just feel it is ugly and that there are ways to just replace the text with pictures without drawing a 9,999px box on your page. As I was saying, this is the first time I have seen this technique and it is very clever. Not sure if I will be adopting it, but if I find myself in a pinch I will be glad I read this article.

Jonathan April 10, 2012 at 11:00 am

Interesting…will try it. Will post results.

Mike Heitzke April 10, 2012 at 10:49 am

The only thing that I’ve come across is when developing responsive sites, when I’m constantly dragging the window around the text I’ve replaced becomes visible since it’s only indented 100%.

Granted, hardly an issue, it’s a personal annoyance I’ve found when developing.

Comments on this entry are closed.