Write better media queries with SASS/SCSS

September 10, 2019

2 min read

To be honest I used to not understand containers and breakpoints. I know it seems simple enough but I simply couldn’t wrap my head around them. Let alone figuring out a decent workflow. So let’s figure out a way, on how to use media queries more efficiently than the traditional way.

Prerequisites:

  • Know the basics of sass/scss.
  • Have a sass/scss workflow rolling.

Using @mixins

When I first learned about media queries I did what everyone was doing. I would have a stylesheet with all my styles and at the bottom of the page, set my media queries. But there is a catch. If you are dealing with a bigger project things can get messy, since you don’t have a clear idea where you css is coming from and what overrides what. And often times is something like one property. Lots of needless scrolling. We can approach our media queries in another fashion, by using scss @mixin‘s.

First we are going to set our breakpoints.

$lg: 1200px;   // 1200px and up
$md: 900px;    // 900px and up
$sm: 600px;    // 600px and up

Then we are going to store the media query functionality in a @mixin.

@mixin small_breakpoint {
  @media (min-width: $sm) {
    @content;
  }
}

@mixin medium_breakpoint {
  @media (min-width: $md) {
    @content;
  }
}

After setting a @mixin with a descriptive name we pass the breakpoint variable as our min-width. @content is where our classes will live.

In our scss file we will have something like this.

.className {
          font-size: 16px;
       ....
     @include small_breakpoint {
              font-size: 20px;
       ....
    }
}

Since we are thinking mobile first, our className starts with font-size 16px. (0px till the value of our $sm variable). The small_breakpoint takes place from our $sm value(600px) till the $md value.

I think this is a much better way to organize our scss.

Multiple Breakpoints

If you are dealing with many breakpoints, where you might want certain parts to change in different breakpoints, the following might be a good use case.

@mixin breakpoint($point) {
  @if ($point == lg) {
    @media (min-width: $lg) {
      @content;
    }
  } @else if ($point == md) {
    @media (min-width: $md) {
      @content;
    }
  } @else if ($point == sm) {
    @media (min-width: $sm) {
      @content;
    }
  }
}

We create a mixin with the name of breakpoint which takes a parameter. The if statement checks that parameter and returns the corresponding media query. The argument will be a name that we pass in our scss like so:

.className {
    ...
    @include breakpoint(md) {
       ....
    }
    ...
}

This way you have more control if you are dealing with many breakpoints.

One use case I found useful is if I have let’s say only one part in a page that I want to apply a different breakpoint, I can do the following.

<div class="container">
  <div class="content">
    . . .
  </div>
  <div class="gallery">
    . . .
  </div>
</div>

Declare the specified breakpoint.

@mixin breakpoint($point) {

        . . .
    @else if ($point == gallery) {
        @media (min-width: 680px) {
            @content
        }
    }
        . . .

}

Apply it in your scss.

.gallery {
    ...
    @include breakpoint(gallery) {
       ....
    }
    ...
}

When I learned about this I was stoked. My stylesheets became much more cleaner and organized.
Hope this post was useful.


Written by John Raptis.
In love with JavaScript, React and programming fundamentals in general.
Follow me on Twitter

© 2020, John Raptis