- October 24, 2013
Fall Back to the Cascade
When we think of responsive design, we typically focus on newfangled mobile devices like smartphones and tablets. But, as front-end developers, we still need to account for older browsers that can’t handle the newest CSS3 techniques when rendering our sites. In the case of responsive design, that means our old friend Internet Explorer 8 (and below) needs some extra handholding when we build our sites with media queries. These browsers don’t support media queries, and since they are still in widespread enough use that we can’t ignore them (~10% of users are still using IE8), we have to come up with new techniques for gracefully degrading our sites.
Internet Explorer fallbacks for desktop styles have typically involved two options: serve a mobile-first layout to IE8 and below, or use a JavaScript polyfill like Respond.js to give these browsers the ability to read media queries and maintain a responsive, fluid design that changes at different breakpoints—just like in a modern browser. The pros and cons of these methods determine whether you would go with A or B for any given project.
Now, we have a third option (courtesy of Chris Eppstein) for serving up CSS in a responsive, mobile-first site for these older browsers: use Sass to take advantage of the cascade, serving a desktop-optimized experience to IE8 and below.
Mixins with Sass
Mixins are reusable blocks of CSS, ranging from one to many lines of code, that can we can then include using just one line elsewhere in our stylesheets. Here’s a simple example using clearfix styles:
Defining a mixin:
Using a mixin:
A mixin for media queries
The secret to powerful mixins is that they can take arguments, which typically define the values that are output in the final CSS. With this in mind, we can build mixins that create media queries for us based on typical breakpoints:
We can take these further by using variables for our media query values, instead of explicit pixel values, so that we have consistent breakpoints to use across the site:
The nice thing about using the mixin we’ve made instead of writing vanilla media queries is that we can include the media query mixin inline inside our styles for the element we’re targeting. We don’t have to put our media queries in a separate declaration after the rest of the styles for that element, so that we’d have to scroll all over our stylesheet to make tweaks for different breakpoints (which was my entire process for responsive design before Sass—my scroll wheel got quite a workout). No more separate files for media queries; they are right where the rest of the styles are for that particular element, where they belong!
Now that we can serve basic media queries with our new mixin, let’s make our desktop styles work for IE8 and friends who can’t read our media queries as they are served right now. With the above Sass, IE8 will simply get the default mobile-first style, which for a desktop browser is not what we want. Returning to our mixin, all we need is to add a conditional based on media query support. We’ll make the conditional take an argument that we set within our stylesheets to either true or false:
Now let’s create a new stylesheet just for these special snowflake, non-media-query-supporting browsers and call it “no-media-queries”:
In this stylesheet, we’ll be declaring our non-support of media queries to instruct the breakpoint mixin how to output our styles.
Now when our Sass compiles, the mixins that are in our styles will output all the CSS inside them. And if you take a peek inside your no-media-queries.css compiled stylesheet, you’ll see that it contains all the styles from your site. Browsers that get this stylesheet will get the last-declared style for each element, making sure the desktop styles are served to desktop browsers that don’t support media queries. If you are writing your CSS mobile-first, with breakpoint declarations occurring in descending order based on increasing screen size, then the magic of the cascade will make sure that your desktop styles are served to IE8 and below using your no-media-queries.css file. Just include this familiar bit of code in your page head to make sure the right browsers get those styles:
Performance considerations
As with any front-end technique, you should consider the specifics of your project when choosing this technique over another. Performance, in particular, should be taken into account. With this Sass fallback, you gain some performance improvements from the fact that you are not using a Javascript polyfill to load your desktop CSS for these browsers.
You should keep in mind the size of your stylesheet, though, as the Sass technique will cause your older browsers to 1) Make an extra HTTP Request for your no-media-queries.css file, and 2) Load all your CSS into one stylesheet, often with duplicate properties defined in subsequent order.
In my experience, these tradeoffs are worth it for large, complex sites that are built with Sass, since polyfills can buckle under the pressure of lots of media queries. Even better, you can clean up duplicate rules in your compiled CSS using tools like CSSCSS, CSS Purge, or CSSLint, so that your final no-media-queries.css is as lean as the other assets on your site.
Looking for more ways to use Sass? Check out Anthony Colangelo’s recently released course, Up and Running with Sass, for The Happy Cog Way, then come back and share how you’ve introduced Sass to your workflow.