Skip to content
This repository
Browse code

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
  techniques.

Fix gh-1149
  • Loading branch information...
commit adecc5da035d6d76b77e3fa95c6abde841073da2 1 parent fac03ef
Nicolas Gallagher authored
2  CHANGELOG.md
Source Rendered
@@ -7,7 +7,7 @@
7 7
 * Separate Normalize.css from the rest of the CSS (#1160).
8 8
 * Improve `console.log` protection (#1107).
9 9
 * Replace hot pink text selection color with a neutral color.
10  
-* Change image replacement technique.
  10
+* Change image replacement technique (#1149).
11 11
 * Code format and consistency changes (#1112).
12 12
 * Rename CSS file and rename JS files and subdirectories.
13 13
 * Update to jQuery 1.8 (#1161).
15  css/main.css
@@ -130,11 +130,18 @@ textarea {
130 130
  */
131 131
 
132 132
 .ir {
133  
-    border: 0;
134  
-    font: 0/0 a;
135  
-    text-shadow: none;
136  
-    color: transparent;
137 133
     background-color: transparent;
  134
+    border: 0;
  135
+    overflow: hidden;
  136
+    /* IE 6/7 fallback */
  137
+    *text-indent: -9999px;
  138
+}
  139
+
  140
+.ir:before {
  141
+    content: "";
  142
+    display: block;
  143
+    width: 0;
  144
+    height: 100%;
138 145
 }
139 146
 
140 147
 /*
7  doc/css.md
Source Rendered
@@ -40,9 +40,10 @@ You are free to modify or add to these base styles as your project requires.
40 40
 
41 41
 #### `.ir`
42 42
 
43  
-Add the `.ir` class to any element you are applying image-replacement to. Be
44  
-sure to include `background-image: url(pathtoimage.png);` for that specific
45  
-element so that image replacement can occur.
  43
+Add the `.ir` class to any element you are applying image-replacement to. When
  44
+replacing an element's content with an image, make sure to also set a specific
  45
+`background-image: url(pathtoimage.png);`, `width`, and `height` so that your
  46
+replacement image appears.
46 47
 
47 48
 #### `.hidden`
48 49
 

13 notes on commit adecc5d

cainmi

Why border: 0; ?

Paul Sham

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.

Hans Christian Reinl
Owner

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

homeara

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.

Tyll Weiß

@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.

Nicolas Gallagher
Owner

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.

homeara

@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.

Paul Sham

@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?

Hans Christian Reinl
Owner

@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!

Shirley Hicks

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.

Paul Sham

@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.

http://jsfiddle.net/paulsham/g2enP/4/

Nicolas Gallagher
Owner

Paul, please open an issue. Thanks.

Santiago Borrazás

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.
Something went wrong with that request. Please try again.