Paulund
2015-03-05 #sass #css

Media Query Sass Mixin

If you do any front-end development over the past couple of years then you would of heard of CSS pre-processors. The most common CSS pre-processors are SASS, LESS, or Stylus. CSS pre-processors are scripts that will compile code and output the results into CSS stylesheets. They allow you to create more dynamic, optimized and organised CSS for your websites.

For more information you can read a previous article I wrote about getting started with Sass. With modern front-end development it's very important to create a responsive design for your websites. You can do this using media queries, they allow you to define certain style for a specific screensize or range of screensizes. This means that you can define how your website will look on mobile devices by stating different styles for a maximum width of 767px (for example). If you are using Sass you will understand the concept of nested selectors.

a
{
    color: red;

    &:hover
    {
        color: green;
    }
}

This allows us you state all rules of a selector inside it's own parentheses, using Sass you can do the samething with media queries. Normally with media queries they will go at the end of the CSS document and will define all the styles under certain sizes.


@media (max-width: 767px)
{
    .header
    {
         // styles for header on mobile
    }

    .content
    {
         // styles for content on mobile
    }

    .footer
    {
         // styles for footer on mobile
    }
}

With Sass we can make it so we organise our code under one selector to make it easier to find styles for a certain element as we can place media queries as nested selectors.


.header
{
    // normal styles for the header

    @media (max-width: 767px)
    {
        // mobile styles for the header
    }

    @media (min-width: 768px) and (max-width: 991px)
    {
        // small tablet styles for the header
    }
}

This makes seeing all the styles for the header very easy because they are all in one place. In this tutorial we are going to see how we can use more features of Sass to make this job even easier for us. The first step is to look at defining breakpoints, meaning the screensizes we are going to process the media queries. When you define styles for different devices it's very likely that we will use the same breakpoints on all our elements in the CSS. Therefore we don't want to have to enter the same breakpoints in code each time when we can use Sass variables, so if we have to change the breakpoints at a later date it makes it very easy.


$mq-xs: "(max-width: 767px)";
$mq-sm: "(min-width: 768px) and (max-width: 991px)";
$mq-md: "(min-width: 992px) and (max-width: 1199px)";
$mq-lg: "(min-width: 1200px)";

.header
{
    // normal styles for the header

    @media #{$mq-xs}
    {
        // mobile styles for the header
    }

    @media #{$mq-sm}
    {
        // small tablet styles for the header
    }
}

We can take this one step further by creating a Mixin to use the different breakpoint sizes, then we can use this mixin in any element of the website. Below is the media query Sass Mixin, first create a parameter in the Mixin so we can pass in the size that we want to use. In this example I'm using the sizes defined by Twitter Bootstrap, if you've used this before you will be familiar with the meanings of xs, sm, md and lg. These are what you will pass into the mixin, then we can use an else if statement to check the breakpoint and return the media query for this breakpoint.


@mixin mq($breakpoint) {

  $mq-xs: "(max-width: 767px)";
  $mq-sm: "(min-width: 768px) and (max-width: 991px)";
  $mq-md: "(min-width: 992px) and (max-width: 1199px)";
  $mq-lg: "(min-width: 1200px)";

  @if $breakpoint == xs {
    @media #{$mq-xs} { @content; }
  }
  @else if $breakpoint == sm {
    @media #{$mq-sm} { @content; }
  }
  @else if $breakpoint == md {
    @media #{$mq-md}  { @content; }
  }
  @else if $breakpoint == lg {
    @media #{$mq-lg}  { @content; }
  }
}

To use this mixin we can do the following, create the Sass selector and inside this use the mixin with the @include keyword, passing in the parameter of the breakpoint, inside the mixin we define all the styles we want to use for the this breakpoint and it will return the media queries for this element.


.content
{
    @include mq(xs) 
    {
        width: 100%;
    }

    @include mq(lg) 
    {
        width: 50%;
    }
}