A new image replacement method or get rid of -9999px

I would like to talk about the image replacement techniques. I think almost everybody was faced with some moments in the layout, for example, when you want to use the graphic object for the page title, and at the same time to keep the text below for the search engines and the printed version. I think no one wants to break semantics of the page.

Here is a little history about this issue

The first most popular technique was FIR (Fahrner Image Replacement), which was released in 2003. It is as simple as a stump, and many layout designers are still using it:

h1.text-hide span {display: none;}
h1.text-hide {
height: 35px; / * height of the replacement image * /
background-image: url("hello-world.gif");
background-repeat: no-repeat;
<h1 class="text-hide"><span>Hello world!</span></h1>

Does it look familiar? Inside of the tag’s background is our image, we add the inline tag that duplicates the text on the image, and then we hide it using display:none;
Many people immediately recognized the curvature of this technique in terms of the semantics and unnecessary html tags. In addition, it is liked by gray optimizers, consequently, some search engines used sanctions to the pages that were overloaded with such objects.

In the same year there was released another replacement technique. It worked like this


padding: HEIGHT_OF_IMAGEpx 0 0 0;
overflow: hidden;
background-image: url ("hello_world.gif");
background-repeat: no-repeat;
height: 0px! important;
height / ** /: HEIGHT_OF_IMAGEpx;

As you can see, there was used a hack for IE5.5, where everything was quite bad with the block model. Subsequently, this technique never took on, because it stopped working in some cases, and in addition many people do not like hacks.


Then another technique was released, namely Phark's Accessible Image Replacement that is the most popular to date, consisting of only one line:
<code lang=""css>.text-hide {
text-indent: -9999px (or -999em);

This technique is not perfect, but if you do not forget about some of the nuances of its work, then it will work in most cases. In particular, you need to check that the text-align was sent in the same direction as the text-indent (in most cases - text-align:left). Also, keep in mind that using it to the element with the property display: inline-block;, this element will go in IE7 following the hidden text.

I was a supporter of -9999px like many others, but at the same time I understood that this is not the best option, and somewhere should be a better solution to this issue. Each time, I was writing -9999px, I thought whether these pixels could affect the website in the future.

The new solution

A few days ago, Zeldman offered this option:
.text-hide {
text-indent: 100%;
white-space: nowrap;
overflow: hidden;

This method solves several problems at once:
  • First, you can be sure that even the longest text that is hidden, will never reach the visual container, even if the length of the text would exceed 9999px.
  • Second, at the beginning a problem was discovered, and then using the same method this problem was resolved. Here is this problem: each time when -9999px was set in the DOM tree there was added an invisible block of this width. If the ordinary browsers were not affected too much by that, then the iPad had serious problems with the performance of the animation (the demo for testing).

However, this method is also not perfect. If the element has padding, then some of text will emerge from behind it. The problem is solved by zeroing the padding for those blocks where the text hides.

Zeldman’s option slightly enlivened the leading front-end developers who are having lively discussions in the comments and blogs.
Also, he was seen by the development team html5boilerplate that now is actively debating on github about introducing a new method to hide the text into a set of helping classes of the boilerplate.

Also, here is offered another method, which has the right to life:

.text-hide {
font: 0/0 serif;
text-shadow: none;
color: transparent;

This method is cross-browser as well, and it is checked in IE7-10, Opera 11.61, Chrome 17.0, Firefox 10.0, and Safari 5.1.2. However, this version will not work for the older browsers, because many of them do not read zero valuation of the font. For example, some of the old Safari instead of zero may read as 6 or 8.

I have taken a lot of information about the history and a new method from this post.

UPD1: Here is another interesting method: CSS image replacement with pseudo-elements (NIR).

UPD2: Chris Coyier has done a great job regarding the techniques of Image Replacement: CSS Image Replacement Museum.
Killer 27 march 2012, 11:49
Vote for this post
Bring it to the Main Page


Leave a Reply

Avaible tags
  • <b>...</b>highlighting important text on the page in bold
  • <i>..</i>highlighting important text on the page in italic
  • <u>...</u>allocated with tag <u> text shownas underlined
  • <s>...</s>allocated with tag <s> text shown as strikethrough
  • <sup>...</sup>, <sub>...</sub>text in the tag <sup> appears as a superscript, <sub> - subscript
  • <blockquote>...</blockquote>For  highlight citation, use the tag <blockquote>
  • <code lang="lang">...</code>highlighting the program code (supported by bash, cpp, cs, css, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, text)
  • <a href="http://...">...</a>link, specify the desired Internet address in the href attribute
  • <img src="http://..." alt="text" />specify the full path of image in the src attribute