Using Sass Mixin for Media Query Is Wrong (Here’s a Better Way)

Every Sass tutorial on the internet will teach you to use mixin for media queries. Why though? All it does is adding unnecessary abstraction.

Every Sass tutorial on the internet will teach you to use mixin for media queries. Why though? All it does is adding unnecessary abstraction.

Why not use the built-in @media block?

Most people say it’s because you can’t use variables in it. Or have to resort to the dirty concatenate syntax like this @media (min-width: #{ $size }).

But there is actually a simple way that solves both those problems. Let’s see how!

Step 1: Create Breakpoint Variables

Decide on your breakpoints and create 2 variables for each of them. One for below that size and the other one for above it:

// Extra Small (mobile)
$below-xs: "max-width:480px";
$above-xs: "min-width:481px";

// Small (tablet)
$below-s: "max-width:768px";
$above-s: "min-width:769px";

// Medium (landscape tablet)
$below-m: "max-width:960px";
$above-m: "min-width:961px";

// Large (content max-width)
$below-l: "max-width:1120px";
$above-l: "min-width:1121px";

Make some special breakpoints too:

$portrait: "orientation: portrait";
$landscape: "orientation: landscape";
$retina: "min-resolution: 192dpi";

Step 2: Use @media with Parentheses

body {
  color: black;
  
  @media ($below-xs) {
    color: green;
  }
}

You can even combine two conditions just like normal @media block:

body {
  color: black;
  
  @media ($above-s) and ($below-m) {
    color: red;
  }
  @media ($below-m) and ($landscape) {
    color: yellow;
  }
}

That’s it! Much cleaner than using fancy mixins right?

Step 3 (Optional): Create Function for Extra Flexibility

In case you need a one-time-use breakpoint, you can create these functions:

@function below( $size-px ) {
  @return "max-width: #{$size-px}";
}

@function above( $size-px ) {
  @return "min-width: #{$size-px}";
}

Then you can use it within the parentheses:

body {
  font-size: 18px;

  @media (below(300px)) {
    font-size: 14px;
  }
}

Conclusion

I believe this is the best way to use media query in Sass. It doesn’t hide any abstraction behind mixin, easier to grasp, and looks tidier.

Oh, and I made a CODEPEN if you want to experiment around with this newfound trick.

Let me know what you think in the comment below 🙂

Default image
Henner Setyono
A web developer who mainly build custom theme for WordPress since 2013. Young enough to never had to deal with using Table as layout.
Leave a Reply