Skip to content

Commit

Permalink
New image replacement approach
Browse files Browse the repository at this point in the history
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
necolas committed Aug 21, 2012
1 parent fac03ef commit adecc5d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
15 changes: 11 additions & 4 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

.ir:before {
content: "";
display: block;
width: 0;
height: 100%;
}

/*
Expand Down
7 changes: 4 additions & 3 deletions doc/css.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down

12 comments on commit adecc5d

@paulsham
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@drublic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@homeara
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Inkdpixels
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@necolas
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@paulsham
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@drublic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@Velochic
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@paulsham
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@necolas
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paul, please open an issue. Thanks.

@sanbor
Copy link

@sanbor sanbor commented on adecc5d Jun 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.