Another approach to mobile first CSS whilst supporting Internet Explorer

Back in December I wrote a blogpost on a LESS approach for mobile first CSS & supporting older IE browsers where I described the current ways (at the time) of creating a IE specific stylesheet from several seperate files. I also described how I thought it should work and since the launch of LESS.js version 1.2.0 it's easier than ever to do.

Roll on 6 months and I have changed how I intend to write my LESS using media query bubbling that keep the media queries within the element which I find easier when editing. Which looks like this.

header {
  background-color: red;
    @media screen only and (min-width: 20em) {
      background-color: blue;
    }
}

An overhead I've still yet to test is performance but I still hazard a guess that it'd be negligible.

A back story.

Last Wednesday (May 30th 2012) Paul Boag wrote a post exclaiming his wishes for LESS which media query pretty much caters for. After a quick firing of tweets Paul also wanted to support those browsers (IE 7 & 8) that don't support CSS3 media queries.

I mentioned that he could use the original technique I blogged about, but this wouldn't allow him to use bubbling. I also mentioned he could 'do a cron job' to strip out the media query rules that Rich Quick mentioned at the Port 80 conference earlier in May (slides).

A Workable Solution.

After much head scratching I found a way to create some internet explorer specific styles within your LESS files whilst still using media query bubbling.

First off we need to 'borrow' the HTML conditional classes that are used within the HTML5 boilerplate. I say borrow as personally I don't take the code verbatim and have stripped out bits, changed little things so it works more for me as I code differently to you as you do to me.

This is the HTML code we need

<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

Now we've got that at the top of our HTML page straight after the doctype declaration we're good to go with diving into our LESS file.

As I mentioned above I've started writing my LESS like this.

header {
  background-color: red;
    @media screen only and (min-width: 20em) {
      background-color: blue;
    }
}

Which when compiled into CSS returns us with this.

header {
  background-color: red;
}

@media screen only and (min-width: 20em) {
  header {
    background-color: blue;
  }
}

Here we have our mobile first or 'base' CSS style to the element (in this case the background colour of the header will be red for devices and browsers that don't support media queries). What we could now do is add some code to the LESS file that'll give the <header> a IE specific class. This is achieved by writing something like this

.lt-ie8&&& { background-color: green; }
.lt-ie8& { background-color: green; }

This uses &&& & which takes the preceding element and then puts the .lt-ie8 class in front of it. So for example writing this LESS.

header {
  background-color: red;

  .lt-ie8&&& {
    background-color: blue;
  }
.lt-ie8& {
    background-color: blue;
  }
}

Gives us this CSS.

header {
  background-color: red;
}
.lt-ie8 header{
  background-color: blue;
}

As you can see we're half way there to media query bubbling anyway so by doing this.

header {
  background-color: red;

  .lt-ie8&&& {
    background-color: blue;
  }
  .lt-ie8&&& {
background-color: blue;
  } 

@media screen only and (min-width: 20em) { background-color: green; } }

We would then, when compiled, get this CSS.

header {
  background-color: red;
}

.lt-ie8 header {
  background-color: blue;
}
  
@media screen only and (min-width: 20em) {
  header {
    background-color: green;
  }
}

This way we can then have our mobile first (or base) style, followed by class specific styles for whichever browsers you are supporting on your project and then all the fun of the fair in the media queries.

Caveat.

Of course this does mean you could be duplicating some of the outputted CSS but a bonus means you could also be more specific. 

But...

Perhaps you only want to give IE6-7 a static, fixed width 'base' design and give IE8 a hybrid fixed/responsive site. With this way of writing your code, you now can do. Easy to create and using this technique easliy maintainable.