CSS IE Media Query Hacks

I’m not a fan of CSS hacks, they are totally unstable and unpredictable pieces of code, usually built on top of another bug… but… unfortunately the way of the web has made it almost impossible to avoid them – I find myself facing a problem I can’t get around without one.

The problem here is CSS media queries and our old fiend Internet Explorer. Internet Explorer only understands the very basic media types such as: media=”screen” but fails to understand media queries like media=”screen and (min-device-width: 450px)”. When it doesn’t recognise this it simply ignores it – that means whole sections of styles are just ignored, and your pages will look completely different to how they are supposed to.

There’s a few ways to include CSS in your files, here I’ll show you how to fix two of these. Both are going to use IE’s Conditional Comments which is probably one of the nicest ways to hack your html. With these you can say include or don’t include sections of html depending on if a user is using IE, and what version they are using – all none IE browsers just see comments which they ignore.

I’m going to target every version that is less then or equal to IE8 – I can say for certain it doesn’t work for IE8 and earlier, I’m just hoping it will be fixed in IE9…

CSS link includes

The first problem is with file includes – I’d always recommend include CSS this way as it’s the cleanest. You’ll have something like this:

  1. <link rel="stylesheet" href="/base.css" type="text/css" media="screen and (min-device-width: 450px)"/>

IE will skip this as it doesn’t understand the part after the “and” and you’ll end up with the wrong display. This is easy to fix as it’s just a single line. We’ll just add another few lines with some conditional comments and IE will pick up those instead. Notice it still links to the same external CSS file:

  1. <!--[if lte IE 8]>
  2. <link rel="stylesheet" href="/base.css" type="text/css" media="screen"/>
  3. <![endif]-->

Now this basically says “if we are using a browser which is IE and it’s less than version 9 then include this additional stylesheet link.

CSS Embedded

The second problem is a little trickier as this involves CSS styles embedded in the HTML, for instance:

  1. <style media="screen and (min-device-width: 450px)">
  2. p { min-width:450; }
  3. </style>

Now we can’t simply wrap the <style> in some conditional statements as it begins a section of CSS and html style comments aren’t technically allowed here, we need to use the CSS style comments: /* and */ . We also need to include another <style> tag for none IE browsers. So here’s the full, rather complicated, solution:

  1. <!--[if lte IE 8]>
  2. <style type="text/css" media="screen">
  3. /*
  4. <![endif]-->
  5. <!--[if !(lte IE 8)]><!-->
  6. <style type="text/css" media="screen and (min-device-width: 450px)">
  7. /*
  8. <![endif]-->
  9. */
  10. p { min-width:450; }
  11. </style>

First we output the code that only IE can see with it’s conditional comment (lines 1-4), which is ignored by other browsers. Notice we also start a css style comment within this section (line 3), see later. Next we use a conditional comment that says to IE don’t include this section (lines 5-8), this contains the media query we want. We still need to end the conditional comment for IE ( line 8 ) but this now appears inside the <style> tag so for other browsers we need to comment this out with CSS comments. The end css style comment (line 9) is also included in IE which is why we needed the first opening comment (line 3). Additionally, the second opening coditional comment (line5) has a closing html comment at the end, this is so non-IE browsers will see a comment, however IE needs to ignore this end comment and continue to its closing conditional comment – this is achieved with the extra “<!”.

I’ve tested this on Opera 10.51, Firefox 3.5.8, IE 6,7,8. I have no reason to believe it will fail on any browser, but let me know!

12 Replies to “CSS IE Media Query Hacks”

  1. You provided a clear, concise answer, to my problem, thank you very much. Sometimes I just feel like *not* supporting IE when I have to tone down on using what is otherwise perfectly compliant code… Too much time spent of figuring workarounds.

  2. Thanks for your comment R. Hill.

    I totally agree, life would be so much simpler without IE! I’m counting down the days, but until then, I only code for compliant browsers, with a limited number of fixes for IE just so it “works”.

    Maybe IE9 will be better…

  3. Greetings Matthew Wilcoxson

    Hope you are doing great and nice to read your article. According to the website http://www.quirksmode.org/dom/w3c_cssom.html I found out that screen.width
    is supported by all browsers listed there. Now I am developing a mobile version of a website and of course it has a separate style sheet. Therefore what I did is the following:

    if(screen.width>50 && screen.width<799)
    {
    document.write('’);
    }
    else
    {
    document.write(”);
    }

    I tested it on firefox-linux, chrome-linux, ie7-vmware and on an android emulator and it works. Do comment and let me know what you think about it.

    Thanking You

    Imran
    Software Engineer

      1. Hi Imran,

        You can certainly use javascript to detect the width and that will work fine in most situations. However, when your pages are viewed in a browser where javascript is not available or turned off you might like to add a CSS include in a section.

        You might also like to try, instead of document.write, use javascript to change the class on (for example) the body, you could then use a single css file for different width. For instance, if the width is detected as wide, then add “wide” to the body class. In the css file the use the class selector .wide .

        Mat

  4. AWSM! i love it! It’s so rare that these CSS hacks work “out-of-the-box”, so it was a nice surprise to find that this one does it’s job without a hitch. thank you.

  5. for the above css embedded solution, all the codes goes inside header tag as far as i am concerned. but for me, i need to hack media query in the stylessheet.css which is same for ie and non-ie browsers. can you suggest any way for that??? i tried using conditional statements but they dont ‘help me.

    1. In most cases you will just need the IE conditional statements to include different CSS files. However, if that isn’t possible there are certain hacks you can use in the CSS which IE understands but others ignore. You should use caution though, these are *hacks* and therefore may not always work correctly, and some may use none standard CSS meaning your CSS won’t fully validate (though it should still work). This website has a good list of these hacks: http://www.webdevout.net/css-hacks . and in particular (using valid CSS):

      • * html {} // IE 6 and below
      • *:first-child+html {} // IE 7 only
      • html>body {} // IE 7 and modern browsers only
      • html>/**/body {} // Modern browsers only (not IE 7)

      You can then extend whichever one you need to target. i.e. * html ul li { color:red; } // only turns text red on list items in IE6.

Leave a Reply to Matthew Wilcoxson Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.