# Media Queries, with Style `mq()` is a [Sass](http://sass-lang.com/ "Sass - Syntactically Awesome Stylesheets") mixin that helps manipulating media queries in an elegant way. As developers and designers we think in pixels and device families, so the `mq()` mixin accepts pixels, ems, keywords… and compiles into ems. We use `mq()` at [the Guardian](http://www.theguardian.com/uk?view=mobile) to effortlessly support older browsers and elegantly abstract media queries, as illustrated in this article posted on the Guardian's developer blog: [Mobile-first Responsive Web Design and IE8](http://www.theguardian.com/info/developer-blog/2013/oct/14/mobile-first-responsive-ie8). ## How to Use It 1. Install with [Bower](http://bower.io/ "BOWER: A package manager for the web"): `bower install sass-mq --save-dev` OR [Download _mq.scss](https://raw.github.com/guardian/sass-mq/master/_mq.scss) to your Sass project. 2. Import the partial in your Sass files and override default settings with your own preferences before the file is imported: ```scss // To enable support for browsers that do not support @media queries, // (IE <= 8, Firefox <= 3, Opera <= 9) set $mq-responsive to false // Create a separate stylesheet served exclusively to these browsers, // meaning @media queries will be rasterized, relying on the cascade itself $mq-responsive: true; // Name your breakpoints in a way that creates a ubiquitous language // across team members. It will improve communication between // stakeholders, designers, developers, and testers. $mq-breakpoints: ( (mobile 300px) (tablet 600px) (desktop 900px) (wide 1260px) // Tweakpoints (desktopAd 810px) (mobileLandscape 480px) ); // Define the breakpoint from the $mq-breakpoints list that should // be used as the target width when outputting a static stylesheet // (i.e. when $mq-responsive is set to 'false'). $mq-static-breakpoint: desktop; @import 'path/to/mq'; ``` 3. Play around with `mq()` (see below) ### Responsive mode ON (default) `mq()` takes up to three optional parameters: - `$from`: _inclusive_ `min-width` boundary - `$to`: _exclusive_ `max-width` boundary - `$and`: additional custom directives Note that `$to` as a keyword is a hard limit. It's not applying styles to the device (see examples below). ```scss .responsive { // Apply styling to mobile and upwards @include mq($from: mobile) { color: red; } // Apply styling up to devices smaller than tablets (exclude tablets) @include mq($to: tablet) { color: blue; } // Same thing, in landscape orientation @include mq($to: tablet, $and: '(orientation: landscape)') { color: hotpink; } // Apply styling to tablets up to desktop (exclude desktop) @include mq(tablet, desktop) { color: green; } } ``` ### Responsive mode OFF To enable support for browsers that do not support `@media` queries, (IE <= 8, Firefox <= 3, Opera <= 9) set `$mq-responsive: false`. Tip: create a separate stylesheet served exclusively to these browsers, for example with conditional comments. When `@media` queries are rasterized, browsers rely on the cascade itself. Learn more about this technique on [Jake’s blog](http://jakearchibald.github.io/sass-ie/ "IE-friendly mobile-first CSS with Sass 3.2"). To avoid rasterizing styles intended for displays larger than what those older browsers typically run on, set `$mq-static-breakpoint` to match a breakpoint from the `$mq-breakpoints` list. The default is `desktop`. The static output will only include `@media` queries that start at or span this breakpoint and which have no custom `$and` directives: ```scss $mq-responsive: false; $mq-static-breakpoint: desktop; .static { // Queries that span or start at desktop are compiled: @include mq($from: mobile) { color: lawngreen; } @include mq(tablet, wide) { color: seagreen; } @include mq($from: desktop) { color: forestgreen; } // But these queries won’t be compiled: @include mq($to: tablet) { color: indianred; } @include mq($to: tablet, $and: '(orientation: landscape)') { color: crimson; } @include mq(mobile, desktop) { color: firebrick; } } ``` ### Adding custom breakpoints ```scss $mq-breakpoints: mq-add-breakpoint(tvscreen, 1920px); .hide-on-tv { @include mq(tvscreen) { display: none; } } ``` ## Test 1. cd into the `test` folder 2. run `sass test.scss test.css --force` 3. there should be a couple of warnings like this one, this is normal: WARNING: Assuming 640 to be in pixels, attempting to convert it into pixels for you on line 25 of ../_mq.scss 4. if `test.css` hasn’t changed (run a `git diff` on it), tests pass ## Inspired By… - https://github.com/alphagov/govuk_frontend_toolkit/blob/master/stylesheets/_conditionals.scss - https://github.com/bits-sass/helpers-responsive/blob/master/_responsive.scss - https://gist.github.com/magsout/5978325 ## On Mobile-first CSS With Legacy Browser Support - http://jakearchibald.github.io/sass-ie/ - http://nicolasgallagher.com/mobile-first-css-sass-and-ie/ - http://cognition.happycog.com/article/fall-back-to-the-cascade - http://www.theguardian.com/info/developer-blog/2013/oct/14/mobile-first-responsive-ie8