Browse files

New image replacement approach

This approach uses a pseudo-element to force the element's content
downwards without covering the background of the element. The overflow
is hidden. For IE 6/7, fallback to the cruder `text-indent` method.

Known advantages:

* Works in IE6+ (although better in IE8+).

* Replaces any content in IE8+, including inner HTML.

* Nothing new for people to learn. Works just like all "traditional" IR
  techniques (unlike NIR, which needs you to add the image using a
  pseudo-element's `content` and relies margins for sprite positioning).

* Doesn't draw a large out-of-element box in modern browsers. You can
  even mix in something like `font: 10px/1 a` to reduce ce the size of
  the "off-screen" box, if you really need to.

* Doesn't have any potential SEO problems from `font-size:0`.

* Doesn't care about any minimum font-size that a browser might have.

* Doesn't have any potential failed-IR problems from inherited styles,
  like text being positioned within the element's visible box (i.e., if
  you use other properties like `text-stroke`).

Known issues:

* Doesn't work when images are off or fail to load (same as every other
  IR technique apart from NIR).

* If the IR'ed element has bottom-padding, then either it needs to be
  removed or the height of the pseudo-element needs to be bumped up
  (e.g., set to 200%).

* Doesn't avoid the `inline-block` bug in IE 6/7 due to the text-indent
  fallback for those browsers.

* Doesn't work on input elements (but they shouldn't be the subject of
  IR anyway).

* There is the potential for some final-result differences between
  IE 6/7 and modern browsers, but this is already the case with other IR

Fix gh-1149
  • Loading branch information...
1 parent fac03ef commit adecc5da035d6d76b77e3fa95c6abde841073da2 @necolas necolas committed Aug 21, 2012
Showing with 16 additions and 8 deletions.
  1. +1 −1
  2. +11 −4 css/main.css
  3. +4 −3 doc/
@@ -7,7 +7,7 @@
* Separate Normalize.css from the rest of the CSS (#1160).
* Improve `console.log` protection (#1107).
* Replace hot pink text selection color with a neutral color.
-* Change image replacement technique.
+* Change image replacement technique (#1149).
* Code format and consistency changes (#1112).
* Rename CSS file and rename JS files and subdirectories.
* Update to jQuery 1.8 (#1161).
@@ -130,11 +130,18 @@ textarea {
.ir {
- border: 0;
- font: 0/0 a;
- text-shadow: none;
- color: transparent;
background-color: transparent;
+ border: 0;
+ overflow: hidden;
+ /* IE 6/7 fallback */
+ *text-indent: -9999px;
+ {
+ content: "";
+ display: block;
+ width: 0;
+ height: 100%;
@@ -40,9 +40,10 @@ You are free to modify or add to these base styles as your project requires.
#### `.ir`
-Add the `.ir` class to any element you are applying image-replacement to. Be
-sure to include `background-image: url(pathtoimage.png);` for that specific
-element so that image replacement can occur.
+Add the `.ir` class to any element you are applying image-replacement to. When
+replacing an element's content with an image, make sure to also set a specific
+`background-image: url(pathtoimage.png);`, `width`, and `height` so that your
+replacement image appears.
#### `.hidden`

12 comments on commit adecc5d


With this new image replacement method, I have noticed a light blue line appear in certain circumstances in Firefox (I tested in Firefox 15.0.1 for Mac). I think the cause is the text highlight in FF might be taller than the text being pushed down 100%.

My quick fix was to increase the .ir:before{height:101%;}.

You could also add a line-height to .ir and push the text lower.


@paulsham Could you please provide a reduced test-case, so we have a better understanding of the problem. That would be awesome.


Note: the replacement technique doesn't work if the .ir element is displaying inline (display: inline;). It might be a good idea to add this to the boilerplate comments.


@homeara Is there any usecase for using an image-replacement method on an inline element? The problem I see is that you can't set dimensions on an inline element anyway, so applying an image to an inline-element while hiding the text itself is pretty much pointless. I could be wrong on this one for sure, it's just my point of view on this helper class.


What @Inkdpixels said.

@paulsham I can't reproduce the issue you described. If you have a test case to demonstrate it, please open an issue and we'll take a look. Thanks.


@Inkdpixels Yes, that makes sense. The image replacement technique for html5boilerplate has been updated twice since the last time I downloaded it. I was trying to add image replacement to a link and it took me a while to figure out why I was getting a smaller version of the background image and the text at the same time. In previous versions, display:block was included in the .ir class defaults, so I didn't need to specify it on an individual element. Thank you for your response.


@drublic @necolas I've been meaning to do it, just been busy. I'm new to Github, what would be the best practice for writing a reduced test-case?


@paulsham Hey, welcome to you! Cris Coyier wrote about Reduced Test Cases. Please use JSFiddle, CodePen or something similar to show how to reproduce the behavior you get. Please concentrate the code that causes the error (don't include your whole page).
Thank you for helping!


Just a comment (and a wave) that as a relative newbie to web development, I've just started watching this thread and the code development. Will be checking out the links you just posted once i have some homework cleared off.


@drublic @necolas Go to the jsfiddle below on Firefox 16.0.1 Mac and do a drag select over the arrows or Select All, you will see a line appear below the image replace from the highlight. My guess it is has to do with a combination between the highlight and the font-family. I solved this on my project was to add a large line-height to .ir. Let me know if this makes sense.


Paul, please open an issue. Thanks.

sanbor commented on adecc5d Jun 17, 2013

I just want to explain to other people what this code does because IMHO it's a little confusing. I would like to see the @necolas approval of my comments (maybe I wrote something incorrect).

.ir {
    background-color: transparent;
    border: 0;

    /* The only relevant line in this class. Overflow:hidden avoids to expand the element
      more than the defined dimensions (that you should specify in your element). */
    overflow: hidden;

    /* IE 6/7 fallback */
    *text-indent: -9999px;

/* The :before pseudo-element generates content before the element's content. */
.ir:before {
    /* The content of this pseudo-element is empty. */
    content: "";

    /* Here is the magic: display: block makes a "jump" in the flow, in result, the element's
     content will be below this pseudo-element. */
    display: block;

    /* This may look a little confusing. We don't care about the width, the display:block will
      push the element's content below this generated pseudo-element. */
    width: 0;

    /* This generated pseudo-element will overflow the element's content. */
    height: 150%;
Please sign in to comment.