Skip to content

Instantly share code, notes, and snippets.

@harriha
Created December 3, 2013 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harriha/7778849 to your computer and use it in GitHub Desktop.
Save harriha/7778849 to your computer and use it in GitHub Desktop.
IE11 bug with dynamic CSS styles

tl;dr

Adding new CSS rules as a string to 'cssText' property of a stylesheet object breaks (some) existing styles in IE11.

The broken styles include viewport adaptation via @-ms-viewport, leading to broken ("zoomed-out desktop version") responsive sites in Windows 8 style IE11 with window width less than 1024px.

Some widely used plugins (incorrectly) use this approach and can thus break your responsive site. Currently, I'm aware of only Facebook's JavaScript SDK doing this - in other words, if you use FB's plugins and include their JS SDK, your responsive site won't work in Windows 8 style IE11 as expected.

MSFT bug report

https://connect.microsoft.com/IE/feedback/details/810593/ie-11-adding-new-css-rules-via-appending-them-to-an-existing-stylesheet-as-a-string-breaks-styling (reported at 2013-12-04)

The same content below. Sample HTML file available in https://dl.dropboxusercontent.com/u/345752/temp/ie-css-bug.html (open in IE11).

Title:

Adding new CSS rules via appending them to an existing stylesheet as a string breaks styling

Description:

It seems that adding new CSS rules as a string to 'cssText' property of a stylesheet object breaks (some) existing styles.

An example:

document.styleSheets[0].cssText += "div { color: yellow; }";

This works (applies the new styles successfully), but it seems that this will also disable/remove some existing CSS rules on the page.

If adding the same new rules via other methods (add a new style tag, use addRule()/insertRule() of an existing CSSStyleSheet object) everything works fine, the problem seems to only apply to the string concatenation approach shown above.

The issue applies to: IE11 (tested on Windows 8 style IE11 on Windows 8.1, desktop IE11 on Windows 8.1, desktop IE11 on Windows 7)

Impact:

Currently I'm aware of this breaking viewport adaptation (@-ms-viewport) and keyframe animations. The first one is a fairly severe issue on responsive websites, since it can make the site unusable in window widths lower that 1024px (especially in the snapped 320px view). Focusing here on that one (sample provided [1]), the other one is reported in FB's bug tracker [2].

Since some social plugins (at least current Facebook JavaScript SDK), and assumably some JS libraries/frameworks as well, use this approach for IE, lots of sites are likely to be broken (speculating here though, only aware of the FB SDK, haven't done extensive research on this).

Additional notes

Regarding the viewport adaptation issue (which applies only to Windows 8 style IE11): after adding CSS dynamically "in the wrong way", navigation back/forward acts oddly, see attached sample [1].

It seems to make things worse that the document.createStyleSheet() [3] was removed in IE11, at least FB JS SDK is currently falling back to string concatenation approach because this API is not present anymore. Code snippet (from the minified src code of that SDK):

...
if(!j.ie()){
    var ea=document.createElement('style');
    ea.type='text/css';
    ea.textContent=z;
    document.getElementsByTagName('head')[0].appendChild(ea);
}
else
    try {
        document.createStyleSheet().cssText=z;
    } catch(fa) {
        if(document.styleSheets[0])
            document.styleSheets[0].cssText+=z;
    }
...

References

About the @-ms-viewport issue/workaround in snapped mode on IE10/IE11 in general:

Related specs:

Named references:

@harriha
Copy link
Author

harriha commented Dec 9, 2013

A workaround for the FB JS SDK issue (and maybe some other 3rd party plugins as well). Add the following to be executed before the FB JS SDK code:

      (function() {
        // A polyfill for createStyleSheet() which isn't present in IE11 anymore.
        // This makes the current Facebook JS SDK to work so that it won't kick
        // IE11 out of the "responsive mode" (= @-ms-viewport still works).
        // Note: this should actually return a CSSStyleSheet object, but this
        // works as well here as long as at least the el is returned.
        document.createStyleSheet = document.createStyleSheet || function(url) {
          var el = document.createElement("style");
          el.href = url;
          document.getElementsByTagName("head")[0].appendChild(el);

          return el;
        };
      })();

If you want, feel free to add this only for IE11 (search for "Trident/7.0" from the userAgent value). Also, the url parameter isn't actually required since FB SDK creates an empty object and appends new styles to its cssText property, but again, some other plugin might do things differently.

@harriha
Copy link
Author

harriha commented Mar 9, 2014

Ahem, that polyfill above is far from perfect and pretty much works only for the case with FB SDK as kindly pointed out by @asamuzakjp . He posted a more comprehensive version to 'Workarounds' section in https://connect.microsoft.com/IE/feedback/details/810593/ie-11-adding-new-css-rules-via-appending-them-to-an-existing-stylesheet-as-a-string-breaks-styling

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