CSS media queries and IE fix

Use CSS media queries to display the same layout on multiple resolutions

Published on November 26, '11
by Serban Ghita
7
Comment
ShareThis

UPDATE 09 January, 2012:
Take a peek at adapt.js is a lightweight JavaScript file that determines which CSS file to load before the browser renders a page.
Make sure you try respond.js - a fast & lightweight polyfill for min/max-width CSS3 Media Queries (for IE 6-8, and more)

If you want to be able to correctly display a fluid design on multiple resolutions (including mobile) then you will probably use CSS Media Queries. CSS Media Queries are not complicated to use and were introduced by CSS3 specifications as an extension of CSS 2.1 media types.

Note that HTML4 supports media types like handheld, but this is poorly supported, old mobiles don't detect it, the modern devices completely ignore it.

CSS Media Queries work fine on modern browsers (IE9, FF, Chrome, Safari, Opera) and on mobile devices (iPhone, Android, Opera Mobile & Mini, Blackberry, IE Mobile 7, etc.)

And of course they don't work on IE < 9.0, but I have a solution that I'm already using on production servers. I wrote a small JavaScript file that reads all the <link> elements from DOM, checks which of them are destined for the current device resolution and applies them.

README | Source code (1.4 kb) | Demo & HTML code

Usage

Read the README file, and check the source code of the DEMO.

...
<head>
<!-- Your .css files. IE6, IE7 and IE8 ignore the media="only all ..." files. -->
   <link rel="stylesheet" type="text/css" href="core.css" />
   <link rel="stylesheet" type="text/css" href="smartphone.css" media="only all and (max-width: 480px)" id="stylesheet-480" />
   <link rel="stylesheet" type="text/css" href="tablets.css" media="only all and (min-width: 480px) and (max-width: 1024px)" id="stylesheet-1024" />
   <link rel="stylesheet" type="text/css" href="wide.css" media="only all and (min-width: 1200px)" id="stylesheet-1280" />
 
<!-- The mighty fix which chooses the correct stylesheet file based on the 
screen resolution, and strips the 'media' attribute so IE6, IE7 and IE8 
can read/interpret it -->
 
<!--[if lt IE 9]>
   <script type="text/javascript" src="/js/css-media-query-ie.js"></script>
<![endif]-->
 
</head>
...

Who needs this fix?

Developers who want to enable CSS3 Media Queries for visitors using IE6, IE7 and IE8

What if I'm using @media all and (max-width:480px) inline inside my core CSS file?

That's smart because it reduces the HTTP requests. In that case you still have to split CSS into sepparate files: core.css smartphone.css desktops.css wide.css, but the code changes slightly:

...
<head>
<!-- Your all-min.css contains all the .css files content together. IE6, IE7 and IE8 will ignore the '@media all ...' inline stuff. -->
<link rel="stylesheet" type="text/css" href="all-min.css" />
 
<!-- 
Let IE6, IE7 and IE8 users have more requests. In the end they are using old browsers right?
First the IE browser will ignore the <link> files with medial="only all ..."
Then css-media-query-ie.js comes into play and chooses the right file, and strips the media property!
 -->
 
<!--[if lt IE 9]>
   <link rel="stylesheet" type="text/css" href="smartphone.css" media="only all and (max-width: 480px)" id="stylesheet-480" />
   <link rel="stylesheet" type="text/css" href="tablets.css" media="only all and (min-width: 480px) and (max-width: 1024px)" id="stylesheet-1024" />
   <link rel="stylesheet" type="text/css" href="wide.css" media="only all and (min-width: 1200px)" id="stylesheet-1280" />
 
   <script type="text/javascript" src="/js/css-media-query-ie.js"></script>
<![endif]-->
 
</head>
...

Screenshots on IE6

Comments

Ian M
Written on: 09 December 2011
But I assume this is a static solution. We have a site we are developing where things dynamically resize/restyle as the resolution changes. I assume this solution will not work in our case.
serban.ghita
Written on: 10 December 2011
Ian, yes it's a static solution, it's applied only 'onload', I can patch it the fix 'onresize' also! Would that be of any help?
Guest
Written on: 14 February 2012
yup!
Guest
Written on: 27 February 2012
Try to open your example in last Chrome and resize window.
Guest
Written on: 02 November 2012
I really like this approach. I tweaked your script a bit with some jquery goodness.
detectAndUseStylesheet = function () {
    var currentWidth = document.body.offsetWidth,
        allSupportedResolutions = [];
    $("link[media][id]").each(function(index, value) {
        allSupportedResolutions.push(parseInt(value.id.match(/[0-9]+$/i)[0]));
    });
    $.each(allSupportedResolutions, function (index, value) {
        if (currentWidth <= value) {
            $($("link[media]")[index]).attr("media", "screen");
        }
    });
};
window.attachEvent('onload', detectAndUseStylesheet);
What do you think?
Nikhil
Written on: 07 February 2013
How about like this?
$(document).ready(function(){
 var currentWidth = document.body.offsetWidth,
        allSupportedResolutions = [];
    $("link[media][id]").each(function(index, value) {
        allSupportedResolutions.push(parseInt(value.id.match(/[0-9]+$/i)[0]));
    });
    $.each(allSupportedResolutions, function (index, value) {
        if (currentWidth <= value) {
            $($("link[media]")[index]).attr("media", "screen");
        }
    });
});
Guest
Written on: 09 July 2014
Thank you so much! This fix my problem on one of my project. Kudos to you mr. developer :)

Post new comment

This blog is intended to foster polite on-topic discussions. Comments failing these requirements and spam will not get published.