ASP.NET Themes Don’t Like IE8’s X-UA-Compatible header; Neither Do I


I ran into an interesting issue a few months ago with IE8 support on sites which use ASP.NET Themes. I’ll talk about the issue and how to fix it. More important, though, I’ll talk about how this small example fits into the whole IE8 / X-UA-Compatible thing, and why I think the way that turned out was bad for everyone.

The Problem: That First Meta Tag

If you’ve got a page that doesn’t render correctly in IE8’s new standards mode, you can add a meta tag to the page which requests that IE8 render it in IE7 mode. The problem I ran into would have been comical if the timing had been better:

  • IE8 only recognizes the X-UA-Compatible header if it’s the first META tag, appearing immediately after the <HEAD> tag
  • The ASP.NET Theme system writes out the theme CSS reference immediately after the <HEAD> tag

Of course, the reason I know that is that I needed to emulate IE7 on a page which was using ASP.NET themes. Video.Show was released in November 2007 and was tested on Firefox 2, Safari 3, and Internet Explorer 7. We built a demo for the MIX 08 conference which ran on the a Pre-Beta 1 release of IE8. Back then, you had to opt-in to super-standards mode, so our IE7 capable markup did just fine. Here’s how that page looked:

IE8 After Header

A little while after that, IE8 Beta 1 came out. One of the significant changes in Beta 1 was that IE8 would render your page in standards mode unless you specifically opted out. That was important to us because our client on that project wanted to be able to use the Video.Show demo we’d built for him, and it didn’t work well in IE8 Beta 1. Here’s how it looked:

IE8 Before Header

The most obvious problem here is that the page background was messed up. The page structure is a bit complex due to the expanding banner at the top, and IE8 calculated that the page header extended to the bottom of the expanding  banner area. Also, the navigation links below the header were showing in a vertical line rather than floating left in a horizontal row. We had a very short turn around time for this project, and the IE8 display quirks weren’t well documented at that time, so tried just adding that fancy new X-UA-Compatible header:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
  <head  id="Head1" runat="server">
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link rel="shortcut icon" href="favicon.ico" />
    <script type="text/javascript" src="Javascript/silverlight.js"></script>

However, here's what was actually rendered:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
  <html xmlns="">
  <head id="Head1">
    <link href="App_Themes/Default/DefaultStyle.css" type="text/css" rel="stylesheet" />
    <meta http-equiv="X-UA-Compatible" content="IE=7" />

 content="IE=7" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link rel="shortcut icon" href="favicon.ico" /><link rel="stylesheet" href="css/lookDefault4.css" type="text/css" />
    <script type="text/javascript" src="Javascript/silverlight.js"></script>

IE8 didn’t recognize the X-UA-Compatible header because the ASP.NET Themes engine always writes out the CSS link as the element in the head section.

How I Fixed It: A Custom Response Header in IIS7

Since I was setting this up in a virtual machine for demo purposes, I could easily make server changes. Here’s how I added that header in IIS7:

IE8 Adding Header

The IE blog has links to instructions on setting those headers various servers:  IIS7.0, IIS6.0, Apache 2.2, Apache 2.0, Apache 1.3. So, yeah, it works, but it’s not perfect. For one, it sets that header for all pages in the site. But, more concerning – what would I have done if I wasn’t able to make changes to the server configuration? If you’re running under IIS7, you can tweak headers with a change to your web.config file:

<?xml version="1.0" encoding="utf-8"?>
        <clear />
        <add name="X-UA-Compatible" value="IE=EmulateIE7">

Otherwise, you can code your way around it with an HTTP Module or something, but the point is that the solution’s so simple anymore. All that brought me back to the X-UA-Compatible conversation from several months ago.

X-UA-Compatible: One Developer’s History

One of the big changes in IE8 is a major shift in the method of selecting the rendering mode for a particular file. The DOCTYPE switch was born a decade ago, and made sense at the time – it used an opt-in model which assumed that a page with a valid DOCTYPE knew what it was doing, so browsers would render the page according to the latest browser standards. It seemed to make sense, but there was trouble in DOCTYPE paradise:

Unfortunately, two key factors, working in concert, have made the DOCTYPE unsustainable as a switch for standards mode:

  1. Egged on by A List Apart and The Web Standards Project, well-intentioned developers of authoring tools began inserting valid, complete DOCTYPEs into the markup their tools generated; and
  2. IE6’s rendering behavior was not updated for five years, leading many developers to assume its rendering was both accurate and unlikely to change.

And so, the IE8 team came up with what most folks would agree is a good idea: opting-in to “standards mode” itself is meaningless unless you specify which standards you’re opting-in to. Targeting “web standards” is great as a platonic ideal, but in reality our pages are rendered by specific browser versions. It’s a lot more practical to opt in to a specific browser version’s rendering mode than a mythical and fluid “standards” mode.

But, then, there was question: since IE8 will be entering a world already populated by billions of web pages written over the past dozen or more years, how should it handle them? Thus began a comedy of errors.

Proving That All Of Us Is Dumber Than Any Of Us

How it’s remembered:

The IE team first announced that it would require pages to opt-in to IE8’s “super-duper standards mode”. The web development community loudly protested, and the IE team changed the default behavior so that pages would be rendered in “super-duper standards mode” by default. We all won!

Here’s what actually happened:

  1. The IE team had it right the first time. There are billions of webpages out there which won’t work well in IE8 without changes.
  2. The IE team forgot that the web development community, by and large, hates them so much that… I don’t even know how to describe it.
  3. The web development community reacted to IE team’s announcement the way they react to just about (except improved CSS support) that the IE team announces. They protested loudly.
  4. The IE team decided to switch it up a bit and did what the web development community was telling them they wanted, and quickly to boot.
  5. We all lost, but almost no one’s admitting to it.

I know this is all old news – Joel Spolsky wrote about this in March. His post was way too long, but the basic idea was that an idealistic solution isn’t all that useful because people don’t install browsers that can’t display their favorite sites. A lot of people disagreed, using two different arguments:

  • It’s not easy, but we have to try to do the right thing” – I agree with the intentions, but I’m cynical here. Users (and IT shops) are still stalling on the upgrade from IE6 to IE7, even though IE7 was a relatively minor upgrade.
  • IE is irrelevant” – These responses were popular in the web standards community, but were themselves irrelevant. Okay, all your friends are running Firefox 3 on their Macbook Air’s, but the browser stats show that IE is still the dominant browser by a large margin. Unfortunate facts are still facts. If you’re hoping that real people will actually use your sites, you have to care about how IE8 works.

Fix Your Pages! Also, Let Them Eat Cake!

I’ve heard a lot of people say that this is a good time for us all to just get this over with and move on. After all, you’ve got several options:

  1. Fix your pages. While I’ve been working with IE8 Beta 1, this is a little easier said than done – there are several IE8 regression bugs which work fine in IE7 and below but fail in IE8. Sure, it’s beta 1, but my point is that this isn’t simply a case of “good HTML / CSS = perfect display in IE8” just yet. I’ve spent several days chasing down several of these bugs, for instance. But, sure, providing that IE8 is really good on CSS 2.1 support, this is the ideal solution. The underlying assumption is annoying, though – the idea is that IE8 is now the authoritative CSS reference. As of now, that’s not at all the case. In some cases my HTML and CSS are correct, work in FF2/3 and IE7 – so why should I have to “fix” them to render in IE8? Arguing that this pain is worthwhile because we’re “doing the right thing for the web” is only valid if we really are improving the HTML/CSS quality of the web, and I’m not convinced this does the trick.
  2. Use the X-UA-Compatible header in your pages. This is listed as the standard response when people list cases where it’s not so easy to fix your HTML. The example above shows a case where a pretty new website built on a pretty modern web framework didn’t support that easily. Forget the case where the HTML is bundled in old CDROM’s or help files written out by installers – a web application built on ASP.NET 3.5 less than a year ago had problems with that approach.
  3. Write the headers some other way. Sure, it was possible in my case, but depending on the site, the skill level of the developers working on the site and their access to the server configuration, this could add up to an unacceptable amount of time. Unacceptable as in “Sorry, we don’t support or recommend IE8 – please use IE7. Thanks!”

Granted, I’m testing with IE8 Beta 1 and IE8 Beta 2 is due out soon, so this situation could improve the situation for actively developed websites. But the operation of the X-UA-Compatible header seems to be pretty much set, and I don’t think it works well with the majority of the billions of HTML documents we’ve already created.


Comments have been disabled for this content.