Fix Bad value X-UA-Compatible once and for all

If you are still stuck having to support older browsers when developing your brand new sites, or even developing sites for an intranet, then chances are you are using the . It’s that that you place in your header to let Internet Explorer know to use a certain rendering engine. There are a few issues with it though, , , site speed to name a few… Lets fix this once and for all!


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

When Internet Explorer comes across this line it will change the engine that is being used to first , if the plugin is installed, and then to Edge (the highest supported document mode of the browser). We need to override this in certain situations as by default, any website running on an Intranet will run in Compatibility Mode () and any website on Microsoft’s will change to it as well.

Note: In Internet Explorer 9 and earlier versions, quirks mode restricted the webpage to the features supported by Microsoft Internet Explorer 5.5. As of , quirks mode behaves differently than the previous versions of the browser. In Internet Explorer 10, quirks mode conforms to the differences specified in the specification. For more info, see Specifying legacy document modes.

So If the above line works what is the problem, why should you fix it and what are the reasons you should fix it?

 Validation

One of the first things I notice is that this meta tag is used on quite, a few, websites already, but it causes validation errors when checking against the HTML5 doctype. When checking on Twitter what to do about the X-UA-Compatible entry here are some of the responses I received.

So should you worry about this? Probably not, but it’s easy to fix and I am a believer that if you can fix a validation error then you should.

Note: I agree that validation is only a guide and I too don’t follow it 100%. It is a guideline of best practices, use it as such.

Rendering Speed

The last nail in the coffin for the Meta fix is the overall rendering speed for your pages. Lets say you are on an Intranet so the website will load up in compatibility mode. The browser will request the page and then start downloading as normal, then it will start rendering as normal… until it comes to your meta tag.

The browser will then have to discard anything that it has done and start all over again. This is the same as causing Layout or Style recalculations, it is just another stop along the way to a fast site.

TMI my friend

Too much information! Now days there are a lot of people out there that don’t use Internet Explorer so you just end up sending this data needlessly. Browsers like Chrome, Firefox, Opera, Safari ..etc… just don’t need to see this, but we send it anyway as adding the meta tag is an easy fix for a problem that only occurs on Internet Explorer.

While the extra 62 bytes are negligible, they are still removable and as we know “Every little helps”. As people are increasingly browsing the internet on some form of mobile device, it starts to become more important to think about all of these small wins. For every byte of data we have to wait, it is another ~ms in the delay to a site being usable. Remember just because you have a fast site, doesn’t mean your user has a fast internet connection.

Visitor loss vs page load time - http://www.pearanalytics.com/blog/2009/how-webpage-load-time-related-to-visitor-loss/

Visitor loss vs page load time
http://www.pearanalytics.com/blog/2009/how-webpage-load-time-related-to-visitor-loss/

Just removing this meta tag could save you lots of time overall. A site that I work on gets on average 6 million page views a month and if you multiply that through out the year it is still a saving of over 260mb of data.

The fix

The fix is simple enough but obviously it is not as easy as dropping in a line of HTML. The new fix will be implemented server side and to make this fix complete we need to

  1. Fix the page validation – This is achieved by simply removing the tag
  2. Rendering speed – Instead of waiting for the browser to see the tag and then change modes we will send the correct mode upfront as a response header
  3. Make sure that we only show the fix for Internet Explorer – We will just use some server side browser detection and only send it to IE

PHP

To add the header in PHP we can just add this to our page


1
2
3
if (isset($_SERVER['HTTP_USER_AGENT']) &amp;&amp;
    (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false))
        header('X-UA-Compatible: IE=edge,chrome=1');

Or you could add it to your .htaccess file like so


1
2
3
4
5
6
<FilesMatch "\.(htm|html|php)$">
    <IfModule mod_headers.c>
        BrowserMatch MSIE ie
        Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie
    </IfModule>
</FilesMatch>

You can change the files that are matched and doing it this way will mean the header isn’t set for every resource (images / javascript / css). That should be everything to make sure your site is running good and you are following best practices for a PHP site.

C# (csharp)

You could add in a new customHeader to your web.config file like below, but as far as I am aware you can’t do browser detection in here.


1
2
3
4
5
6
7
8
9
<configuration>
  <system.webServer>
     <httpProtocol>
        <customHeaders>
           <add name="X-UA-Compatible" value="IE=Edge,chrome=1" />
        </customHeaders>
     </httpProtocol>
  </system.webServer>
</configuration>

So the better solution would be to inherit all your pages from a custom Controller (or extend from System.Web.UI.Page if you are using WebForms) and add in the following check.


1
2
3
if (Request.ServerVariables["HTTP_USER_AGENT"] != null &&
                Request.ServerVariables["HTTP_USER_AGENT"].ToString().IndexOf("MSIE") > -1)
                    Response.AddHeader("X-UA-Compatible", "IE=edge,chrome=1");

So that’s it… “ Bad value X-UA-Compatible for http-equiv on element meta.” fixed for good…

In the future we won’t need to include this in our projects but for now we have to just stick with it. Let’s hope that everyone adopts Windows 8 😉

  • NetGuru

    The better fix is to use the HTML4 transitional doctype with a table based layout with some light css, this is more compatible and works on intranets, extranets and the internet alike.

    • James

      “A table-based layout”? I hope you’re kidding.

      • http://www.ryne.me/ Ryne Pittman

        Trolls gonna troll my brotha! :(

    • Creepy

      haha… unbelievable…

  • Guest

    Yeah

  • http://twitter.com/iamtzi tzi

    It could be better to test if the apache module “setenvif” is enabled before using it.

    Thanks for sharing this !

  • http://www.facebook.com/madhavajay Madhava Jay

    Doesnt this defeat the purpose of chrome=1, if the user_agent contains MSIE and you dont output the tag, then IE will never switch chrome frame on.

    • Denny Caldwell

      You’re reading it backwards. It outputs the tag if the user agent contains MSIE

  • aymanrb

    A better implementation is to replace the Comma between “IE=Edge,chrome=1″ with a semicolon to be like “IE=Edge;chrome=1″. This would prevent the breaking of in-page iframes, or at least that was the case with me with IE9 :)

  • Pappu

    Hi Check your image

  • Denny Caldwell

    You’re really over engineering here, Aaron, and for no real benefit. I do agree that using the header instead of the meta tag is better although it really doesn’t make much difference at all – and only including the header if the user is using IE is arguably worse.

    The tag doesn’t pass HTML5 validation for a reason: It’s not supposed to. The “X-” stands for “Experimental” and is reserved for openly non-HTML-standard tags. That aside, as the Twittersphere pointed out, HTML validation is just there as a guideline – to help you find issues with your markup that could cause problems when rendering – and this isn’t one of them.

    Unless I’m totally off mark, when IE loads the page, it doesn’t actually render the entire thing then open chrome and re-render it again. When IE hits that meta tag, it launches Chrome Frame which begins rendering the page immediately – even before IE has finished downloading all the contents of that page. IE *will* continue to download the rest of the scripts on the page, but they’re never rendered. That’s why (with Chrome Frame installed) if you open the IE developer tools and go to the HTML tag you’ll get a permanent, “Loading…” and if you go to the Script tag, you don’t see any scripts. Again, this isn’t to say you shouldn’t use the header instead of the meta tag. It’s just not quite as bleak of a circumstance as it sounded from your article.

    As you point out, you’re only saving yourself 62 bytes of data on non-IE pages by only including the tag or header for IE browsers. This doesn’t really amount to anything in the real world – unless your user is a time traveler from 1987 and they brought their modem with them. And remember – moving into a header doesn’t actually save 62 bytes – since the header is still transferred to the client, just not in the HTML. In reality, you’re saving yourself about 31 bytes as:

    …would be:
    X-UA-Compatible: IE=edge, chrome=1

    …as a header.

    The trouble is that you’ve now added complexity to your code to detect the browser, and with that, additional processing time on the server to execute that code. You may say, “Well, how much work is it REALLY on the server for it to execute that one little if statement?” to which I would reply, “How much bandwidth is it REALLY to download that extra 34 bytes of header in non-IE browsers?”

    On a positive note, your article is nicely done. I especially like that you include examples in both C# and PHP, and by more than one means to boot. I look forward to reading more from you in the future.

    • Garet Claborn

      I largely disagree here.

      If done as a header, your server is already going through the overhead of examining them so it isn’t as problematic as adding real logic; depending on how you enable that process..or really it wouldnt be so bad to just send those to everyone’s header without the check.

      The real benefit of sending via header is taking care of this ahead of time. The cycles lost when a browser realizes “oh shoot, wrong rendering methods” is the main concern IMHO.

      This will cause the DOM parsing to restart just as character encoding meta tag can which can cause a noticeable issue on the client side. Since we can take care of this server-side I believe it is worthwhile. A few more years and we thankfully wont have to worry of it much anymore though.

      • validatethis

        @garetclaborn:disqus yup in just a few more years we will never have to worry about this. Infact we are pretty close even now!

        @dennycaldwell:disqus I definitely don’t think this is over engineering… if you had said over thinking then yeah I agree.

        The solutions above are elegant and simple and in many cases are “set and forget”, like the htaccess version. If asked if the server should process something like this or if the client should then the server wins every time as there is no transfer of data.

        In today’s modern web we need to be able to squeeze every last byte out of the users request so its good to get this one out the way and not have to think about it again. Its such a good idea that it is even included in the HTML5 Boilerplate

  • Cammy

    Hey, great post. However my issue was that in my master pages (Have a big project running) I had inline code ABOVE the which totally screwed me over. IE was putting them in as whitespace and never added the doctype to my page at all. Swaping the order around though thankfully helped me!

  • ZityMap
    1
    2
    if (isset($_SERVER['HTTP_USER_AGENT']) &amp;&amp; (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false))
            echo('<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />');

    Hello. Somebody like this solution?

    • Mr Grey

      Works great for me!

    • huz

      In which tag I should use this in wordpress header? I used it inside <?php tag but its not working by this.

      • http://sastaservers.com Shirish Chincholimath

        Can you please tell me where did you add these lines on code in WordPress?

        • Kopfsache

          in WordPress you add this line in the header.php (Design > Editor) just like this:

          • mayur

            i have use this meta but not a validation in W3C so please provide me code for validation in W3C

    • mike

      Thank you!

  • Matt

    Minor comment, adding a HTTP header overrides the ‘forced’ compatibility mode setting, where a meta tag does not.

  • Martin Stoeckli

    Just what i was looking for, thanks. The solution with the .htaccess file is a “do it once and forget” solution, so why not do the best we can?

  • Matt Soria

    Is this what the H5BP is doing in its .htaccess with this:

    Header set X-UA-Compatible “IE=edge,chrome=1″
    # `mod_headers` can’t match based on the content-type, however, we only
    # want to send this header for HTML pages and not for the other resources

    Header unset X-UA-Compatible

    ?

  • Hriza muh

    how to fix it on blogspot platform?

  • http://www.elliotjreed.com/ Elliot Reed

    Love the article! Just out of interest, why can we not just do something like the following?

    !–[if IE ]

    ![endif]–

  • craig

    how is checking the user agent string for MSIE of any help when IE11 doesn’t report itself as being MSIE?

    http://msdn.microsoft.com/en-gb/library/ms537503(v=vs.85).aspx

    Also it is my understanding that from IE10, IE no longer recognises conditional comments.

    Plus, last but not least Chrome Frame for IE is no longer available nor supported by Google. Though the mind boggles why you would want to run Chrome in IE, just run Chrome!

    From what I can tell the only solution currently is to use…

    and ignore the validation error.
    Unless someone does know a fix for the problem?

  • Michele Cariglia

    Thank you so much!

  • Rich

    Just a side note, Google released their Web Starter Toolkit (https://developers.google.com/web/starter-kit/) recently which is kind of like their own best practice boilerplate and they have the x-ua-compatible tag in the head of their html file. I guess we can take that for what it’s worth…

  • agent_rock
    • Terry

      This just shows how to detect a browser and nothing to do with setting the X-UA value

  • Tony Franco

    Hi! I´m very new to all this… how i remove the tag? Thanks and Regards!

  • Cameron Clare

    Thanks heaps, I don’t care if it’s “over-engineering.” I used the .htaccess method, and, as I’ve usually found, any kind of .htaccess fix trumps all the others.

    I’m one of those OCD types. I hate errors and “invalidation.” So cheers for relieving that one :)

  • Kai

    Very good article, helped me a lot! Thanks :)

  • jen milender

    thanks validatethis.co.uk

  • Charley wilsone

    Hi,
    I am unable to install the WordPress plugin in my site. I says “plugin does not have a valid header”. Please can somebody help?

    • tyrone wise

      Hi friend,
      One can install those Web plugins manually by uploading them to server. Within the X-theme folder that you have downloaded, locate the zip files under:

      X/framework/plugins/

      Now unzip all plugin files and with the help of FTP client software (i.e. FileZilla Client), upload that in server at following path:

      ROOT/wp-content/plugins/

      Now login to your WordPress back-end visit “Plugins > Installed plugins” section to activate those plugins.

      • gen denver

        well said, thanks buddy..

  • http://www.mwmoriarty.com/ Michael Moriarty

    In the .htaccess file that comes with H5BP Boilerplate 5.3.0 it says that .htaccess slows down Apache and recommends using httpd.conf instead. What are your thoughts?

    Adding to or creating an .htaccess file for the website would be less work than adding a line of code to your section for each page.

  • http://www.mwmoriarty.com/ Michael Moriarty

    H5BP Boilerplate 5.3.0 .htaccess file has this section:
    # ———————————————————————-
    # | Document modes |
    # ———————————————————————-

    # Force Internet Explorer 8/9/10 to render pages in the highest mode
    # available in the various cases when it may not.
    #
    # https://hsivonen.fi/doctype/#ie8
    #
    # (!) Starting with Internet Explorer 11, document modes are deprecated.
    # If your business still relies on older web apps and services that were
    # designed for older versions of Internet Explorer, you might want to
    # consider enabling `Enterprise Mode` throughout your company.
    #
    # https://msdn.microsoft.com/en-us/library/ie/bg182625.aspx#docmode
    # http://blogs.msdn.com/b/ie/archive/2014/04/02/stay-up-to-date-with-enterprise-mode-for-internet-explorer-11.aspx

    Header set X-UA-Compatible “IE=edge”

    # `mod_headers` cannot match based on the content-type, however,
    # the `X-UA-Compatible` response header should be send only for
    # HTML documents and not for the other resources.

    Header unset X-UA-Compatible