The HTML5 Shim vs Internet Explorer Emulation Mode

Contributing Editor

In this article I’ll discuss techniques which are avoided by good HTML developers. Not everyone is as conscientious as SitePoint readers; you’ve probably encountered those who are happy to accept quick fixes regardless of the future pain it inflicts.

When IE7 was released it broke sites designed for IE6. Developers had relied on IE6-specific techniques, workarounds and hacks which failed in the newer browser. Many sites had to be fixed. Developers deserve their share of the blame, but IE6 ruled supreme for many years so it’s not surprising people were annoyed by the changes. Microsoft were attacked even though they were only implementing the standards we demanded.

To avoid a similar backlash in IE8, Microsoft introduced Document Compatibility modes. If your site worked in IE7 but failed in IE8, you could add the following meta tag to your page:


<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

or send an HTTP header:


X-UA-Compatible: IE=EmulateIE7

IE8 would mimic the behavior of IE7 and everything would magically work again. At the time of writing, IE9 features no less than eight Document Compatibility modes, including the slightly bizarre “IE5″ setting which renders content as if it were displayed in IE7 quirks mode which is similar to IE5. For more details, refer to Defining Document Compatibility at MSDN.

Document Compatibility mode is unique to Internet Explorer. Other browsers have not suffered the same fate because:

  • IE has been around longer than most of its competitors and evolved during a period when W3C standards were in their infancy. Other vendors were able to adopt a more stable set of HTML features from the start.
  • Microsoft sell software to businesses and have long-term contractual commitments. Other vendors can add, modify or drop features without facing legal or financial consequences.
  • Microsoft’s two-year IE release schedules inevitably contain more fundamental changes than regular updates to Chrome, Firefox, Safari and Opera.

Compatibility modes were intended to be a quick fix. If you encountered issues following an IE release you could temporarily use a compatibility mode while you updated your code.

Does that happen? No. Look around the web today and you’ll find IE=EmulateIE7 meta tags everywhere. I’ve even seen it used on newly-released sites — after all, it’s easier to target one rendering engine than attempt cross-browser development in IE7, 8 and 9.

Compatibility Mode and IE9

Using IE5, IE7, EmulateIE7, IE8 or EmulateIE8 modes causes temporary amnesia for IE9. The browser forgets HTML5. It loses CSS3 effects such as rounded corners and box shadows. Features such as SVGs disappear.

However, it also causes unexpected issues…

iframes and Other Child Objects

Let’s imagine you’ve created an HTML5 widget. It works in IE7, 8 and 9 because you’ve added the HTML5 shim:


<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Another developer now adds your widget to their site using an iframe. Not the most elegant solution, but it’s quick and easy.

Question: if the parent page is opened in IE9 but uses IE=EmulateIE7, what rendering engine will the iframed page use?

Answer: the parent page and all child objects — including the iframe — will render in IE7 mode. Even though your widget is IE7/8 compatible, your widget will break because:

  1. IE7, 8 and 9 render the iframe in IE7 mode, but
  2. the HTML5 shim is only loaded in IE7 and 8.

The result: IE7/8 work as expected but IE9 fails.

The Solution

It’s tempting to add a compatibility mode override to your widget’s HTML head, e.g.


<meta http-equiv="X-UA-Compatible" content="IE=edge" />

It won’t work. The parent page has overall control; it sets the rendering mode once and it remains that way until all assets have loaded.

As far as I’m aware, there is only one fix — load the HTML5 shim in ALL versions of IE:


<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

While IE9 and all future versions do not require the shim, you can’t guarantee your widget won’t ever appear in a page where a compatibility mode is set.

Ughh — I feel unclean. Web development is a messy business.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://niteodesign.com Blake Petersen

    Nice article! Curious, which site’s are you referring to when you say some more-recent ones are using EmulateIE7? I’d love to take a looksie and try to make sense of the decision, lol.

    Thanks Craig!

    • http://www.optimalworks.net/ Craig Buckler

      The problem occurred for me recently and, while I can’t name and shame, the problem affected a the site of a major UK media company who certainly have redesigned their site within the past three years.

  • http://www.lunadesign.org awasson

    Hi Craig,
    Some good points there… I had a little shiver reading the IE7 bits…. Man those were dark days ; )

    I have used shiv a few times to get IE6 – 7 to behave but I try my damnedest not to use iframes as much as I can. I do use IE=edge in all of my sites and when necessary I use a conditional comment to deal with whatever pesky IE6 issues arise.

    Beyond that IE just makes me shake my head. IE9 is arguably the best of the IE line and for the most part I’m really happy with it but going forward with a more “responsive” approach to websites, it sure leaves a lot to desire in the way of CCS3/HTML5 support. Still way behind Chrome, Safari & Firefox.

    • http://www.optimalworks.net/ Craig Buckler

      IE9 is the best version of IE since – well, IE6 (when it was initially released, of course!)

      While I avoid iframes, it’s shocking that emulation mode affects them and removes all those nice HTML5/CSS3 effects you toiled over in IE9.

  • http://yuhongbao.blogspot.com Yuhong Bao

    A better fix:

    if (!document.documentMode || (document.documentMode < 9))
    {
    document.write("”);
    }

  • http://yuhongbao.blogspot.com Yuhong Bao

    Sorry, posting again as the html got lost:
    <!–[if lt IE 9]>
    <script>
    if (!document.documentMode || (document.documentMode < 9))
    {
    document.write("<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>”);
    }
    <![endif]–>

    • http://yuhongbao.blogspot.com Yuhong Bao

      Change <!–[if lt IE 9]> to <!–[if IE]>, of course.

    • http://yuhongbao.blogspot.com Yuhong Bao

      And add a </script> before the <![endif]–>, of course.