The star hack in IE8 and dynamic stylesheets

July 3rd, 2009. Tagged: CSS, IE

CSS hacks

⇓ skip if you already know about the star and underscore hacks

For most CSS tasks, there are only two hacks that are straighforward to use, easy to spot and maintain (delete down the road), easy to understand. The star hack that targets IE6 and 7 and the underscore hack that targets IE6.

Consider this:

.box {
    background: red; /* normal browsers */
    *background: blue;  /* IE 6 and 7 */
    _background: green; /* IE6 */
}

In normal browsers, you get red. Normal browsers ignore *background and _background because they are invalid. IE6 and 7 have a bug that accepts the definition prefixed with a star as if you defined it as "background". And because *background comes after background, IE6 and 7 will say "oh, the latest one overwrites". Similarly the underscore. But the _ bug was fixed in IE7 and only IE6 still treats _background as if it was background.

So the code above will paint a red box in normal browsers, blue in IE7 and green in IE6. IE8 is also a normal browser so IE8 in IE8 mode will give you red. BTW, this technique applies to all properties, not only background.

Surprise

The problem I found is when you set styles dynamically. Say you have a bunch of CSS content as a string and you want to create a new style tag and shove the code there. I've blogged about this before.

When you set styles dynamically IE8 behaves as IE7.

🙁 , 🙁 and double 🙁

» Here's a demo/test page.

The code:

var def = ".box {background: red; *background: blue; _background: green;} ";
var ss = document.createElement('style');
ss.setAttribute("type", "text/css");
if (ss.textContent) { // FF, Safari
    ss.textContent = def;
} else {
    ss.styleSheet.cssText = def; // FF, IE
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(ss);

This will give you blue in IE8, which is really unfortunate.

UPDATE: Thanks to a question from @stubbornella, I updated the test with setting the inline style attribute, as opposed to creating a new <style> tag. Turns out IE8 behaves as normal IE8 in this case and ignores the star and the underscore hacks. So only creating a new style tag dynamically via JavaScript is the problem.

Tell your friends about this post on Facebook and Twitter

Sorry, comments disabled and hidden due to excessive spam.

Meanwhile, hit me up on twitter @stoyanstefanov