This article discusses the problems we encountered with the "Compatibility View" setting in Internet Explorer. We dig into Browser Modes and Document Modes to understand why this setting exists and how to work around it by setting the X-UA-COMPATIBLE header server side or META tag client side.
The "Compatibility View" setting in Internet Explorer makes the browser pretend to be an older version (IE7) when displaying pages.
Microsoft's reasoning behind this is that a large number sites and internal web applications were designed for a specific version of Internet Explorer. When people upgrade to newer versions of IE, those sites may not work correctly anymore, if at all. Compatibility View makes old sites work again, but it comes with a cost.
When we launched a new site for one of our clients, their internal help desk got flooded with reports that the site was not rendering properly. Yet when we checked the site again, everything seemed normal in IE9, IE10 and IE11 - the supported IE versions.
We discovered that most non-power users within the corporate network had the "display in Compatibility View" setting enabled in their Internet Explorer settings for the corporate domain (the corporate site we relaunched).
IMAGE
This single checkbox setting turned out to be the cause of all the wailing and gnashing of teeth.
Understanding the IE Compatibility View setting
When IE Compatibility View is enabled for a certain domain three things happen:
-
IE will set its Browser Mode to "IE7" to identify itself as IE7. As a result, when the browser makes requests the relevant part of the user-agent string is set to "MSIE 7.0". Web Servers receiving the request will assume it came from an IE7 browser, and can act upon that information. This means you could send back a different response based on which browser version the request came from, if you wanted.
-
IE's Document Mode is also set to IE7. This will determine how IE displays the layout and how javascript and the DOM behave: IE will display the site as if it's IE7.
-
IE's Version Vector (stored in a registry key) is temporarily overridden to 7. IE uses the Version Vector when it processes conditional statements such as:
<!-- [if IE7] <link rel="stylesheet" type="text/css" href="/css/ie7.css"/><![endif] -->
<!-- [if gte IE8] <link rel="stylesheet" type="text/css" href="/css/ie8.css"/><![endif] -->
In this scenario with Compatibility View enabled, IE versions higher than 7 will still use ie7.css and ignore ie8.css.
IE Compatibility View in corporate environments
You may find that IE Compatibility View is enabled in your browser for a certain site, yet you never added it to Compatibility View websites list.
There are two possible causes:
-
Your network administrators pushed the site(s) to your Compatibility View site list via Microsoft's Group Policy Management.
-
Your network administrators marked the site as an intranet site, and the checkbox "Display intranet sites in Compatibility View" is ticked. To learn more about this baviour, read: Stack Overflow - Why compatibility mode for intranet sites.
IMAGE
How to get around IE Compatibility View mode?
Modern websites that use the latest generation of html markup and css layout techniques can and will break in modern IE versions with IE Compatibility mode enabled.
To work around this problem we, as web developers, need a way say: "This is modern code. If you are a modern version of IE but happen to have Compatibility View mode enabled, ignore it for this particular site."
X-UA-COMPATIBLE to the rescue! It forces Internet Explorer to use a specific Document Mode to render our web page. We can either set this value using a META tag in the page source code, or add it as a custom header in our HTTP response.
The values we can set are:
- "IE=edge"
- "IE=11", "IE=EmulateIE11"
- "IE=10", "IE=EmulateIE10"
- "IE=9", "IE=EmulateIE9
- "IE=8", "IE=EmulateIE8"
- "IE=7", "IE=EmulateIE7"
- "IE=5"
The most useful X-UA-COMPATIBLE value is "IE=edge", which means "use the highest, most recent Document Mode available". The other values have their use but are beyond the scope of this article. To learn more about supported values and use cases, read: Stack Overflow: What's the difference is X-UA-Compatible exists?.
To start using X-UA-Compatible you can either add it as a META tag to your html source, or include it as an HTTP header. Here's how:
Adding the X-UA-Compatible tag to your html source
Place the following META tag as high as possible inside the
tags, preferably right after<title></title>:
<head>
<title>Example Site</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
</head>
There are several ways to do this:
Drupal 7 - option 1: add the META tag to html.tpl.php
-
If your theme doesn't already have a
html.tpl.phpfile, copy it over from the base theme you're using (if any) or fromDRUPALROOT/modules/system/html.tpl.php -
Add the header directly under the title tag and save
Drupal 7 - option 2: inject the META tag via drupal_add_html_head():
In your theme's template.php, implement template_preprocess_html():
/**
* Implements template_preprocess_html()
*/
function YOUR_THEME_NAME_preprocess_html(&$vars) {
$tag = array(
'#type' => 'html_tag',
'#tag' => 'meta',
'#attributes' => array(
'http-equiv' => 'X-UA-Compatible',
'content' => 'IE=edge',
),
'#weight' => -99999,
);
drupal_add_html_head($tag, 'my_custom_ie_metatag');
}
Remark: we're setting the weight attribute to -9999 to make sure this element gets added tag as high up as possible in the <head> tag.
Django 1.9: add a middleware class that adds the header to the response object:
class XUACompatibleMiddleware(object):
def process_response(self, request, response):
response['X-UA-Compatible'] = 'IE=edge'
return response
Django middleware example courtesy of https://gist.github.com/vstoykov/4989570
Adding the X-UA-COMPATIBLE header to the HTTP response
Setting X-UA-Compatible as an HTTP header is usually a better idea than setting it using the META tag because:
-
It keeps your html source cleaner.
-
It avoids the HTML5 validation error that occurs, since it's a non-standard (Microsoft-only) META tag.
-
It ensures that the directive gets parsed by IE before any other such directives in the html source. As soon as IE detects the directive in the HTTP response it will set the Document Mode and won't even bother with trying to interpret similar Document Mode-changing directives in the html source.
Option 1: make your web framework set the HTTP header
In php here's how you'd set the header:
<?php header('X-UA-Compatible: IE=edge'); ?>
Where and when you need to do this depends on how your application works.
If you're using Drupal 7, you can set an HTTP header with drupal_add_http_header().
A good place to do so would be in hook_init():
/**
* Implements hook_init().
*/
function YOUR_MODULE_NAME_init() {
drupal_add_http_header('X-UA-Compatible', 'IE=edge');
}
If you want to make sure this header is only added on responses to normal html requests and not on responses to ajax and other requests, you'll want to use hook_page_build().
This can also be a solution if you're having caching issues and you're finding that the header doesn't get set every time.
/**
* Implements hook_page_build().
*/
function YOUR_MODULE_NAME_page_build(&$page) {
drupal_add_http_header('X-UA-Compatible', 'IE=edge');
}
Option 2: make your web server set the HTTP header
Apache 2.2, Apache 2.4 (using .htaccess)
Add the following directive to the <IfModule mod_headers.c> block at the bottom of the .htaccess file, located in your Drupal root directory:
<IfModule mod_headers.c>
[...]
Header set X-UA-Compatible "IE=Edge"
</IfModule>
Remark: Make sure to use Header set instead of Header add. Using the latter can cause unforeseen consequences if the X-UA-Compatible header is already present. Header set will correctly replace any header with this name or create one if none exists.
Nginx (using a vhost)
Add the following to your site's vhost config file, on Debian systems most likely located at /etc/nginx/sites-available :
server {
[...]
add_header X-UA-Compatible "IE=Edge";
}
Microsoft IIS7 (using web.conf)
Add the following snippet inside the <system.webServer> block in the web.conf file, located in your Drupal root directory:
<system.webServer>
[...]
<httpProtocol>
<customHeaders>
<add name="X-UA-Compatible" value="IE=edge" />
</customHeaders>
</httpProtocol>
[...]
</system.webServer>
Option 3: make your HTTP accelerator set the HTTP header
HTTP Accelerators such as Varnish can also be configured to set HTTP headers:
Add the following to your .vcl file, usually located at /etc/varnish on Debian systems:
sub vcl_deliver {
if( resp.http.Content-Type ~ "text/html" ) {
set resp.http.X-UA-Compatible = "IE=edge";
}
}
Closing thoughts
X-UA-Compatible is a workaround for IE Compatibility View, which is a workaround for companies refusing to update old IE sites, which is inexcusable.
Neither X-UA-Compatible nor this whole article should have to exist.





