My Media Query Mixin

01 April 2013

I've written quitealotabout media queries; Playing with LESS then Sass(SCSS) has made me create mixin upon mixin to help my front-end development workflow. I think I've finally settled on something (famous last words!) that works for me and want to share it. Because sharing is good, right?

and the winner is…

You say what?

This mixin allows you to define your major or minor breakpoint in pixels (it automatically converts to EMs), define the media query whether it be min or max, width or height, device height or device width. The mixin has 4 variables in it, most of which are predefined.

$point : is the pixel value for your major or minor breakpoint

$IE9 : is predefined as false, changing this to true would include the IE9 conditional class of CSS

$query1 : this is for either min,max, min-device, or max-device defining the first part of the media query. Predefined as min

$query2 : this if for either width or height defining the second part of the media query. Predefined as max.

It also fantastically has the option to copy the media query content and create a snippet prefixed with an class that'd be picked up by IE8 or less as specified in your HTML with this code -

<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->

So because it can give min,max,width,height options let's go through the examples.

What's up $doc-font-size

In my _variables.scss I have two variables that are related to the document font-size. One for line-height and one for font-size. The $doc-font-size variable in the mixin above needs to be defined in your Sass for this to work. Mine is generally set to 16 and my variables would read

$doc-font-size: 16;
$doc-line-height: 24;

Although, we won't be using the line-height in this mixin or any examples

Examples...

1) A simple min-width media query

So your media query you'd write in SCSS would be -

.example {
@include mq(320) {
width: 100%;
}
}

Which would result in -

@media screen and (min-width: 20em) {
.example {
width: 100%;
}
}

So giving the mixin no other arguements than a numeric value (a pixel value) would give you the staple media query of min-width.

Here we've just given the $IE9 variable a value of true giving a simple max-width media query and a conditional class for IE8.

From these examples I hope you can see that instead of min or max you can also use min-device and max-device so that you can target 'devices' if you wish to.

Major Breakpoints

I work with two kinds of CSS3 media queries in mind when developing responsive websites. Major and minor breakpoints. As mentioned in a slidedeck from Stephanie and Bryan of Yiibu.

With Sass you can create some variables for what you like to determine as 'major' breakpoints and include them as necessary in the media query mixin.

For example you could have predefined major breakpoints like this -

$mobile: 320;
$tablet: 760;
$desktop: 1200;

You can then include it in the mixin like this -

@include mq($mobile, false, max) {
.example {
width: 100%;
}
}

Which would give you this result -

@media screen and (max-width: 20em) {
.example {
width: 100%;
}
}

Nesting that media query

One of the great things about Sass is the ability to nest your CSS. But you can also nest mixins. This means you can nest this mixin. That's pretty cool. So as an example you can do something like this -

.class > mixin or mixin > .class

From all the examples I've given above I've been putting the media query mixin within the .class but you can do this the other way around and with Sass it outputs the same code. As shown in this example -

Media Query Bubbling or Nesting

As I've written previously I write my media queries 'inline' with the element I'm editing rather than tagging it on to the bottom of my stylesheet. This, I feel, allows for better code organisation and a more OO 'modular' approach. This makes it easy to find the code you may need to edit and allows for a better 'mobile first' approach.

.lt-ie9 & {
// put the IE8 and below CSS declarations here
/* IE8 and below */
// if you need IE7 as well then prefix the CSS with a *
/* IE7 and below */
// if you need IE6 as well then prefix the CSS with a _
/* IE6 */
}

Where you would be using CSS hacks to will Internet Explorer 6 and 7 into submission.

Portrait / Landscape mixin

Because you can nest media queries within each other. I've also created a little mixin for defining the portrait or landscape media query.

Of course you can just include the media query by itself if you need to.

100% pure adrenaline!

After all this, what I've effectively done is recreate a Compass plugin by Sam and Mason - Breakpoint. You could say I've reinvented the wheel a little. But I like my mixin, it works for me and how I want to code. Also I don't use Compass because I like 'my own' code and to know what each mixin I use is doing. But that's just me. If you're already a Compass user your mindset might be in favour of using this plugin. As with all things, it depends.

Copy and Paste

As well as copying and pasting the code above, I've also added it on codepen and to my (work in progress (just started)) Sass mixin library - Sassifaction.