IE8 and the X-UA-Compatible situation

Disclaimer upfront: any opinions expressed in this post are the sole opinion of myself and do not necessarily reflect the opinion of any of my employers, past and/or present.

Update: Make sure not to miss Part 2: Solutions of this article to see what your two best ways of dealing with IE are!

If you’re a web developer, you’ll already know that Internet Explorer 8 (Final) was released to the public recently, and with it comes the “X-UA-Compatible” header, a mechanic that the IE Team devised as their way of “not breaking the Web”. In this two-part article I will first explain what IE8’s behavior is with regard to this header, then, in the next piece, provide you with technical solutions that allow you to maintain control over the display and functionality of your website(s) no matter what your constraints may be.

Let’s start from the top: the X-UA-Compatible header, which can be set as both an HTTP-level header or as a <meta> tag inside your HTML document, allows you to specify which rendering engine you want IE8 to use; setting it to IE=EmulateIE7 will tell IE8 to use the IE7 rendering engine; setting it to IE=8 will enforce the IE8 Standards Mode engine. It is designed to be forward-compatible, so a hypothetical IE9 will support it, as will an IE10, and so forth. If you want to simply enforce the latest and greatest engine in all currentand future versions of IE, you can set the X-UA-Compatible header to IE=Edge, which is the instruction to “always use the most cutting edge engine available”.

Just as examples, here are both the HTTP and the <meta> tag ways of setting X-UA-Compatible:

Header set X-UA-Compatible "IE=8"

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

On top of this header implementation, Microsoft has also added a blacklist of sites to IE8 that, by default, are instructed to render in IE7 Compatibility View mode. This list, formally called the Windows Internet Explorer 8 Compatibility View List, is actively maintained by Microsoft and contains (currently) over 2400 top-level domains for sites that are not deemed or are proven not to be ready to handle IE8’s far more Standards-compliant rendering than its predecessor. I’ll get to that later on; what’s important to know right now is that this list is only used by IE8 if the user has chosen to use it. The default setup of IE8, “IE8 Express Setup”, enables the use of the list. The Custom Setup routine allows you to choose not to use it, so if you run, maintain or develop for a site whose top-level domain is on this list, you can’t simply assume that the visitor in IE8 is going to get the IE7 rendering engine (or the IE8 one for that matter, but more on that, again, later on). Also important to note is that the list is top-level domains only but applies to any and all sub-domains for those domains.

As the cherry on top, there is the Compatibility View button that is present in the UI (the chrome) of IE8 if and only if the X-UA-Compatible header is not specified in any way; neither on HTTP level nor inside the HTML via <meta> tag (it will also not show up in the UI on sites that are blacklisted, as the blacklist is really just an implicit way of saying IE=EmulateIE7). This button allows the user to toggle between default (IE8 Standards) mode and IE7 Compatibility View. If you allow it to, IE8 will send your clicking behavior of this button back to Microsoft as a means of gathering data for which sites should be on their blacklist.

Lastly, before going into the nitty-gritty, I want to point out that this entire EmulateIE7 / IE8 Standards Mode stuff only matters for sites with a DOCTYPE. If you’re actively choosing to rendering in Quirks mode, stop doing that. No, I’m not joking, you should really be doing web development properly by now and that means the use of DOCTYPEs. But, for completeness’ sake, Quirks mode documents are not affected by the X-UA-Compatible header.

IE8 findings

I’ve done a lot of testing, and every so often I would discover another behavior piece that meant I either had to re-do all my tests or add a new dimension to my results (and thus do even more tests than previously thought). At this point, the number of permutations and combinations is so large that I’m not going to bother you with the full set of results. Instead, I will just list off a couple of the important behavioral patterns I’ve gleaned from all this.

Let me start with something that will cause some immediate concern among many of you:

It is entirely possible to encounter IE8 sending the IE7 User Agent string to the server while using the IE8 Standards Mode rendering engine; conversely, you can encounter the IE8 User Agent string while rendering in IE7’s engine.

If there ever was an argument against merely sniffing the User Agent string to base your code off of, this would be it.

Now let’s go over some rendering engine logic.

  • By default, out of the box, IE8 will choose to render a website in IE8 Standards Mode
  • If it loads a page from a blacklisted domain, IE8 will use the IE7 Compatibility View rendering engine
  • If the user presses the Compatibility View button on a non-blacklisted domain, IE8 will use the IE7 Compatibility View rendering engine
  • If the website specifies X-UA-Compatible to IE=EmulateIE7, the Compatibility View button will be hidden and IE7’s rendering engine will be used
  • If the website specifies X-UA-Compatible to IE=EmulateIE7 via the <meta> tag (only) but there is a<script> element in the source code before the <meta> tag, then IE8 will actually use its IE8 Standards Mode rendering engine
  • If the website specifies X-UA-Compatible to IE=8 via HTTP header and X-UA-Compatible to IE=EmulateIE7 via <meta> tag, then EmulateIE7 will prevail and IE8 will render using the IE7 Compatibility View rendering engine
  • …providing you don’t have a <script> element above that <meta> tag, of course.

Are you a little confused yet? It’s okay if you are, this is decidedly more complex than any other browser makes it. Let’s power through!

  • If a domain is blacklisted or the Compatibility View button is pressed by the user, which puts the entire domain you’re on in Compatibility mode, IE8 will send the User Agent string for IE7 to the server (it is at this point undecided which rendering engine is going to be used)
  • If a blacklisted domain is framing a non-blacklisted website using HTML Frames, then the non-blacklisted website will inherit the rendering engine and User Agent choices that IE8 made for the blacklisted domain…
  • …and vice versa.

What that means is that if your site is viewed through a Google Images’ frame or, for example, the DiggBar, your domain is effectively blacklisted—completely regardless of whether your own domain is on Microsoft’s list or not. The reverse is also true, so if you create a frame on a non-blacklisted domain that points to a blacklisted domain, you will be requesting that blacklisted website with the IE8 User Agent string.

For both scenarios, the framed site (i.e. the target) still has full control to override the Rendering Engine in IE8 by specifying the X-UA-Compatible header.

By the way, I used the Google Images frame and the Diggbar as examples because both and are on the blacklist, and there’s no telling if they’ll ever be removed until the day they’re just not on that list anymore.

Now, while wrapping up the second piece with the technical solutions on how to deal with all of these permutations and possible rendering engine/UA combinations, feel free to ask me any questions using Twitter for comments—something I instated on this blog a while ago, but which now makes even more sense thanks to Twitter’s recent changes to the @replies system. Just use the comment link below to send me your comments and/or questions. This is the time to get your specific question answered in my second post!

If you liked this, you should follow me on Twitter!