IE-friendly mobile-first CSS

IE-friendly mobile-first CSS

Almost everyone we know and do business with has a smart phone, and these people are using their phones to browse online. A common argument to not doing mobile-first responsive design is supporting Internet Explorer 8 and under. In this post I'll talk about doing both with IE-friendly mobile-first CSS.

Why do mobile-first?

Two great reasons:

  1. Not everyone has a generous data plan
  2. Not everyone has the latest, most powerful smart phone

When we go mobile-first, we serve only the files that the mobile user will be using, and ensure that those files are optimized for their devices. That includes optimizing images for a user's screen size with responsive images, making sure your videos are fluid and responsive, as well as optimizing your CSS and JS so as to only load what's required for each browser.

Why should I not do mobile-first?

Because it's easier to go desktop-first when you have to add support for Internet Explorer 8 and other browsers that don't support media queries. And that's about it.

Mobile-first responsive design with CSS preprocessors

The old way of doing responsive design

What often happens with the usual responsive design that isn't mobile-first, is that CSS is declared for desktop and then overridden for mobile. This means that we specify a value twice when we could either specify it only once or not at all (if it isn't needed). We want our body background colour to be white for mobile and pink for desktop. The usual responsive design would declare it pink and then use a media query that targets phones to override it and make it white. Here's an example of what not to do:

/* don't do this! ;) */
body {
    background-color: #f39;
}

/* lots of CSS goes here */
/* ... */
/* and then somewhere at the bottom of your file */

@media (max-width: 959px) {
    body {
        background-color: #fff;
    }
}

The better way using in-context media queries

The following snippet shows how we can use Stylus, one of the many flavours of CSS preprocessor available, to declare our background colour only for desktop:

desktop = '(min-width: 960px)'
pink = #f39

body
    @media desktop
        background-color pink

That's literally 5 lines of code where 2 of them are variable declarations, compared to the regular CSS way, which is 8 lines, and the media query possibly lives quite far from the original declaration. With media queries nested inside of the element, we can see everything in context. With this approach, we can modularize components, and break modules out into separate files to keep it cleaner.

IE-friendly mobile-first CSS with Gulp

So I have mobile-first CSS—now what do I do for Internet Explorer?

Unfortunately, Internet Explorer 8 and under cannot read media queries, which means that our mobile-first websites end up looking terrible in these browsers. In order to convert our mobile-first CSS into IE-friendly mobile-first CSS, we need to parse all of the CSS declared in the media queries, write it to a separate stylesheet, and load that stylesheet for Internet Explorer 8 and under. Like CSS preprocessors, we can post-process CSS with similar tools. This solution uses a build tool called Gulp and a couple of contributor modules to post-process the CSS file. Just add the following to your Gulpfile.js:

var gulp = require('gulp');
var nmq = require('gulp-no-media-queries');
var rename = require('gulp-rename');

gulp.task('iestyles', function () {
    gulp.src('css/styles.css')
    .pipe(nmq({
        width: '960px' || '480px'
    }))
    .pipe(rename(function(path){
        path.basename = 'ie';
        path.extname = '.css';
    }))
    .pipe(gulp.dest('dist/css'));
});

The stars of the show are no-media-queries and the Gulp plugin gulp-no-media-queries. There's also a Grunt plugin. The Gulpfile code above, once run through Gulp with its helper modules, will get the compiled file in css/styles.css, run it through a tool that strips out media queries, and output the results in dist/css/ie.css. Once we have all of the required Node.js modules, we can run our Gulpfile:

gulp iestyles

This solution is great but developer beware: when developing your CSS, you need to declare your styles in order of most mobile to least mobile, i.e. no breakpoints (phones), tablet breakpoint, and then desktop breakpoint. You can selectively choose which media queries to pluck out styles for. The above configuration assumes that Internet Explorer will use both tablet (480px) and desktop (960px) styles.

Conclusion

So there you have it! That's how you can get IE-friendly mobile-first CSS. A summary of the tools and approaches used:

  • Node.js for using all of the mentioned build tools
  • Stylus for CSS-preprocessing
  • modular components with media queries nested with their module, declared from smallest screen to largest
  • Gulp.js + some helper modules for stripping out media queries, renaming the file, and outputting it where we want it

Mobile-first Responsive Design while still supporting old browsers used to be harder but with great build tools like Node.js, Stylus, Grunt, and Gulp, we can configure our development environment and automate our build processes to make CSS development for phones and old browsers a breeze.