LessCSS, Import and Media Queries

Today I found out the Media Queries are not supported at all in IE8. Not sure how I missed this, only that I haven’t used media queries extensively in any project until now. I have just finished off a site that has an adaptive layout for table and mobile. Having completed the majority of development in Chrome and I yesterday moved on to the dreaded cross-browser testing.

To my surprise when I open it up in IE9 there was appeared to be no serious issues. A pleasant surprise, the text lacked text-shadow in a few places, but this is an aesthetic issue not a downright broken issue so I can live with it. Feeling bolder I moved on to IE8 and was very disappointed when the site was a wreck, not slightly broken but very broken.

This was a bit unexpected as I tend to develop using well known patterns which only occasionally need tweaking. Something else must have been the issue. Following a brief conversation with a dev friend he pointed out that IE8 doesn’t support media queries. All of my layout and navigation was defined in media query, hence the massive fail.

The solution was a straight foward approach:

  1. Copy the CSS out of the media query into a separate file
  2. Conditionally include it in the header for IE8 (and below)

This approach does however pose a maintenance overhead, if I make changes to the desktop CSS this needs to be carried through to the external file. Ideally I want to be able to maintain one file which is referenced in the main file. The media query spec does not allow you to use a CSS import inside it, so this approach is not available.

Fortunately I use a CSS pre-processor to create my CSS, I use {less}, less allows you to use multiple files and import them into a single output file. My approach was to simply copy the less into an external file and use the @import syntax in the main file. I could then reference the compiled external file in a conditional comment.

@media only screen and (min-width: 769px) {
  @import "desktop";
}

This did not work unfortunately, the less parser currently does not understand this construct and the import is ignored. It is a well known issue and has been discussed for some time. It is fixed for now in the master branch and is scheduled for the 1.4 release but isn’t out yet. Instead I have used the following work around.

Wrap the code required in a mixin in an external file (desktop.less) i.e.

.desktop() {
  less code...
}

Then import the code outside of the media query and call the mixin inside the media query (main.less) i.e.

@import "desktop";
@media only screen and (min-width: 769px) {
  .desktop();
}

Finally I created an extra file which includes the code outside of the media query which can be compiled and conditionally added (ie.less) i.e.

@import "desktop";
.desktop();

One file to maintain, compiled into the main CSS file, and and another CSS file for conditional inclusion. When 1.4 is released my first approach will be available and you won’t need the extra file, until then this is a good work arund.

Ignoring the 10%

Browser support and cross-browser testing is a tricky subject. As a veteran of the browser wars I’ve seen a number of browsers dominate for a while then tail off as a new generation invariably comes through. In each generation we as web developers look to be in a better place but are always seem to be held back by the legacy of previous generations.

Back in the early 2000’s there were basically two browsers of note (I am deliberately generalising here and am well aware there were more than two browsers) IE6 and Netscape, roughly speaking it was a 90/10 split. IE6 was the ground breaking browser, way better then Netscape, and it was believe me. As a developer you spent most of your time developing to IE6 well aware of the fact it probably broke a bit in Netscape. Never a comfortable situation but it did allow you to take advantage of the better features in IE6 which seemed a good compromise.

Fast forward a few years and the next chapter in the browser wars, the standards movement. Raising Microsoft out of their slumber it pushed the web forward, IE7 was awful, IE6 the bane of developers lives with IE8 and Firefox the leading lights. It was bad for a few years but we moved forward, slowly but surely we started leaving behind IE6, sure there was still 10% of people using it but sacrificing these users for the good of the 90% was acceptable.

And now we are in modern times, Chrome has emerged as the new darling of browsers, IE9/10 makes it again one of the contenders, Firefox is still in the mix and everywhere mobile is the new must support platform. And then there is IE8… Yep you guessed it, representing about 10% of your users.

Given the importance being placed on mobile as a platform, and the fact that most mobile/tablet computers have fairly good support for modern standards is it time to sacrifice the 10% again. Some big sites and big players such as Google have already signalled the end of IE8, is it time for this to become the norm? IE8 usage will only drop and mobile looks set to increase, in my eyes the time is now…