6

There seems to be a bug in IE when cascading dynamic stylesheets. Does anyone know if there is a workaround? Consider this:

<head>
    <style>#test{background:red;}</style>
</head>
<body>
    <div id="test">test</div>
    <script>
        var link = document.createElement('link');
        var style = document.getElementsByTagName('style')[0];
        link.rel = 'stylesheet';
        link.href = 'test.css';
        style.parentNode.insertBefore(link, style);
    </script>
</body>

The injected 'test.css' contains #test{background:green}.

Even though we place the <link> before the <style> tag, IE7+ will override the styles with the injected stylesheet and apply green as background.

FF/Chrome do this the right way and lets the style tag take precedence over the injected link tag so the background stays red.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • `style` tags in the `body` are invalid (even though tolerated by all browsers). Still, I agree with you that what FF & co. do is the expected behaviour. – Pekka Jul 01 '10 at 13:53
  • yea, the same effect happens in the head. I just wanted to state a clear example. – David Hellsing Jul 01 '10 at 13:55
  • The dynamic link is missing a `type` property - hardly the root of the problem but should be fixed to exclude obscure bugs. Also, I would post a valid `head` based example for the same reason. Could it be that the dynamic element isn't created in IE at all? Do other styles embedded this way work? Which versions of IE does this apply to? – Pekka Jul 01 '10 at 14:01
  • The dynamic element is created since it actually overrides the styles. Corrected the code as you suggested if it makes more sense. – David Hellsing Jul 01 '10 at 14:21

1 Answers1

2

I think the cause for this is the way IE defines insertBefore. In IE only you may pass only one parameter into the insertBefore method and it will behave the same as appendChild. I think what they do is insert it THEN move it. If they render at the point of insertion then it would be rendering properly.

The only work around I can think of is as follows (which isn't ideal):

    var link = document.createElement('link');
    var style = document.getElementsByTagName('style')[0];
    var newstyle = style.cloneNode(true);
    link.rel = 'stylesheet';
    link.href = 'test.css';
    style.parentNode.insertBefore(link, style);
    style.replaceNode(newstyle);
Michael Sparks
  • 645
  • 3
  • 10