Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reassess IR techniques #1149

Closed
necolas opened this issue Jul 29, 2012 · 23 comments
Closed

Reassess IR techniques #1149

necolas opened this issue Jul 29, 2012 · 23 comments
Milestone

Comments

@necolas
Copy link
Member

necolas commented Jul 29, 2012

Various issues need to be considered and the pros/cons of techniques reassessed:
#1108
#1125
#1144

@necolas
Copy link
Member Author

necolas commented Aug 15, 2012

​I've been playing around with another IR technique. It's a hybrid approach; not sure if it's been thought of before. Below is its simplest form (without any extra cruft that you might need for button or hiding child br in IE 6/7):

.ir {
    overflow: hidden;
    *text-indent: -999em;
}

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

Demo / Test case

The pseudo-element forces the content downwards without covering up the background of the element. Then the overflow is hidden. For IE 6/7, we fall back to the text-indent method.

From what I've learnt so far...

Pros:

  • 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 content and use margins for sprite positioning).
  • Doesn't draw an out-of-element box any greater than is needed in modern browsers (so that iPad1 issue Scott was trying to work around seems like to be avoided). You can even mix in something like font: 10px/1 a; to reduce 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).
  • Doesn't appear to require !important anywhere.

Cons:

  • Doesn't work when images are off or fail to load (same as every other IR technique apart from NIR).
  • Needs to nuke padding, otherwise bottom-padding can result in some text still showing. Alternatively, defend against padding by adding > 100% height.
  • Still suffers from the inline-block bug in IE 6/7 due to the text-indent fallback for those browsers.
  • Won't work on input elements (does anyone still use these with IR? they shouldn't).
  • Potential for some differences between IE 6/7 and modern browsers...but this is already the case with both the text-indent and "font crushing" methods.
  • If there is a non-rare, non-IE browser out there that doesn't support pseudo-elements, then it's not going to work.

I could do with some people to help test this out a bit more (across different browsers, inc. mobile) and find any additional problems. Also, opinions about this.

cc @h5bp/html5-boilerplate @scottkellum @brendanf @chriseppstein @scottjehl

@MarcusJT
Copy link

Looks identical in Google Chrome Canary (Windows), Android 4.1.1 browser, and Chrome for Android 4.x

@sergiocerrutti
Copy link

Why do you think it's better than this one?

.hide-text {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

I prefer to avoid pseudo-elements for tricks (just for visual things), it's a fact that they are very slow when browsers renders them and parse the selector.

@necolas
Copy link
Member Author

necolas commented Aug 16, 2012

Why do you think it's better than this one?

Because that method is pretty buggy

I prefer to avoid pseudo-elements for tricks (just for visual things), it's a fact that they are very slow when browsers renders them and parse the selector.

Where is the data to back that up? Pseudo-elements are already used everywhere that the clearfix hack is used. And rendering a pseudo-element isn't going to be as slow as loading an image. It seems like an non-issue.

@sergiocerrutti
Copy link

There is no link to show you this thing (sorry), but I had time to test them with Chrome's CSS profiler tool creating a list of a lot of elements with a before (doing a lot of visual things) and another HTML replacing before with span nodes with the same behavior. Chrome's profiler tool said both ::after and ::before pseudo-elements are 5-10% slower (while parsing) than a normal HTML node. Of course I don't know why but maybe you can give it a try.

Anyway, I have test it just in Chrome so it could differ in other browsers.

So, having a trick without pseudo-element it's faster than with it, more if we use it in a large website with a lot of IRs.

One more thing, why the way I said is buggy, I never had problems with it since I use it.

@necolas
Copy link
Member Author

necolas commented Aug 16, 2012

I'm not going to lose any sleep over 2ms + 10%.

I never had problems with it since I use it.

I did a bunch of tests of it last time we looked at IR in HTML5 Boilerplate, it has plenty of issues and edge-case problems that make it unsuitable to roll into this project: aa0396e

@mkantor
Copy link

mkantor commented Aug 16, 2012

Another con (probably a small one):

  • Makes the ::before pseudo-element unusable for other purposes.

@brianblakely
Copy link
Member

@mkantor I thought about that too, but I think you likely won't need it for IR elements, or can simply use ::after.

Personally, I'm favoring the font-crush, unless someone can authoritatively tell me that it will kill SEO. For the time being, losing IE7 support again is too big.

@necolas
Copy link
Member Author

necolas commented Aug 16, 2012

losing IE7 support again is too big

IE 6/7 are both supported by this technique as it includes the same old negative text-indent method for them. The font-crushing method actually leaves a bit of residue in IE6/7.

@brianblakely
Copy link
Member

@necolas Ah, I meant in the case of inline-block'd elements, which was major thorn in my side until your excellent font-crush solution.

@necolas
Copy link
Member Author

necolas commented Aug 16, 2012

I meant in the case of inline-block'd elements

Yeah, that kinda sucks if you need IE 6/7 support with inline blocks. Hmmm

@maxw3st
Copy link

maxw3st commented Aug 17, 2012

Not sure if this is what you're looking for. The code above doesn't hide text for me, but this does:

.ir {    
    *text-indent: -999em;
    background-image: url('https://www.google.de/logos/2012/opening_ceremony-2012-sr.png');
    width: 114px;     
    height: 41px;
}

.ir:before {     
    content: "";
    margin-left: -999em;
}

Here's the Fiddle: http://jsfiddle.net/maxw3st/bLfUK/
I only tested this in Firefox and Chrome. Looked the same in both.

@pklauzinski
Copy link

I know this isn't for mobile, but FYI.. using negative ems to hide text doesn't work on Android ICS. I had to use negative px values for it to actually hide, e.g. -999px (Droid Razr ICS).

@necolas
Copy link
Member Author

necolas commented Aug 17, 2012

The code above doesn't hide text for me, but this does.

How does it not hide text? Did you open the fiddle? Your example isn't much different to just using negative text-indent. It has pretty much all the same problems.

I know this isn't for mobile...

It is for mobile. But the negative text-indent is only for IE 6/7

@sergiocerrutti
Copy link

That performance is importante in large websites, but you're right, it's nothing in real cases.
I've tested in my Android 2.3.6 Browser and it's perfect as it's in Chrome21, Canary23, Firefox15, Opera12 and Safari6, all of them in a Mac.

Thank you necolas!

@sergiocerrutti
Copy link

I've used this for text replacement (which finally is the same) and the behavior is perfect:

h2 {
  background-color: rgb(245, 245, 245);
  height: 48px;
  border-bottom: 1px solid rgb(222, 222, 222);
  position: relative;
  overflow: hidden;
}
  h2:after {
    content: "Elige un método de pago";
    position: absolute; top: 0; left: 24px;
    font-size: 18px; font-weight: bold; line-height: 48px;
  }
  h2:before { content: ""; display: block; width: 0; height: 100%; }

@Gavrisimo
Copy link

@necolas hey man, do you think this is bug or am I using .ir class wrong?

.ir class is not working with input[type=submit] as seen on this fiddle:

http://jsfiddle.net/8BSL3/

@davidmurdoch
Copy link

adecc5d

Known issues:
...

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

Use a button: http://jsfiddle.net/musicisair/8BSL3/1/

@Gavrisimo
Copy link

Yup, I knew there is something I was missing here... :) Thanks!

@Gavrisimo
Copy link

@davidmurdoch Hmmm it seems this is not working in firefox? O_O

http://i.imgur.com/BwXzl.png

@necolas
Copy link
Member Author

necolas commented Sep 13, 2012

You havent set any dimensions on the element that is receiving IR

@Gavrisimo
Copy link

Look again in css field: http://jsfiddle.net/musicisair/8BSL3/1/

a, button {
    display: block;
    width: 128px;
    height: 128px;
    background-image: url('http://2.bp.blogspot.com/_6rROSHI_zZ4/SfY4yPxlHFI/AAAAAAAABpY/0iPyrZOreHc/S220/cat_avatar_0065_www.free-avatars.com.jpg');
}

@necolas
Copy link
Member Author

necolas commented Sep 13, 2012

Oh yeah, I see. You'll have to use an element within button then, and file a bug with the Firefox team :). Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants