Media Queries with Sass Mixins and Maps

Technophile - Aug 12 '22 - - Dev Community

Hi, there! Today, you will learn how to use media queries with Sass mixins and maps. There are 3 stages, each one of them focusing on different approaches and concepts.

I hope you enjoy it!

Stage I

Let's start with a mixin and we can dive into more complex concepts with maps.

First, create a mixin that takes no argument and return a constant @media query.

_media-query.scss

@mixin mq() {
   @media only screen and (min-width: 50em) {
     @content;
  }
}
Enter fullscreen mode Exit fullscreen mode

If you have tried this out in the main file:

style.scss

@use 'media-query' as *;

:root {
  --fs-400: 1rem;

  @include mq() {
    --fs-400: 1.125rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Compiled CSS should look like this:

style.css

:root {
  --fs-400: 1rem;
}

@media only screen and (min-width: 50em) {
  :root {
    --fs-400: 1.125rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Stage II

Now, it is time to make it dynamic by passing a parameter inside the map:

_media-query.scss

@mixin mq($size) {
   @media only screen and (min-width: $size) {
     @content;
  }
}
Enter fullscreen mode Exit fullscreen mode

And, in the main file, try passing an argument:

style.scss

@use 'media-query' as *;

:root {
  --fs-400: 1rem;

  @include mq(50em) {
    --fs-400: 1.125rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

The result should look the same.


Stage III

However, it is still possible to make it more dynamic.

Now, you can add a map and use with our mixin. Maps are equivalent to objects in JavaScript or dictionaries in Python. First set some breakpoints inside the map:

_media-query.scss

$breakpoints: (
  sm: 30em,
  md: 50em,
  lg: 75em,
);
Enter fullscreen mode Exit fullscreen mode

When using a map, it ensures that you can only use keys within the map, which prevents imaginary numbers floating around and make your code more robust.

Now, in order to get the value within maps, you can use map-get() function which takes 2 arguments, the map you declared and the key inside that map. And, it will return a value that is attached to the key. Now, using this concept...:

_media-query.scss

$breakpoints: (
  sm: 30em,
  md: 50em,
  lg: 75em,
);

@mixin mq($key) {
  $size: map-get($breakpoints, $key);

  @media only screen and (min-width: $size) {
    @content;
  }
}
Enter fullscreen mode Exit fullscreen mode

In the main file, use a key from $breakpoints map as an argument inside your mq() mixin:

style.scss

@use 'media-query' as *;

:root {
  --fs-400: 1rem;

  @include mq('md') {
    --fs-400: 1.125rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: you can quote or unquote the argument inside mq() function according to your own preference. I like quoting it.:)

Compiled CSS file:

style.css

:root {
  --fs-400: 1rem;
}

@media only screen and (min-width: 50em) {
  :root {
    --fs-400: 1.125rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Also, as a bonus tip, you can improve the validation of your media query by including @if and @else rule:

_media-query.scss

$breakpoints: (
  sm: 30em,
  md: 50em,
  lg: 75em,
);

@mixin mq($key) {
  $size: map-get($breakpoints, $key);

  @if ($size) {
    @media only screen and (min-width: $size) {
      @content;
    }
  } @else {
    @error '`#{$key}` does not exist in the $breakpoints';
  }
}
Enter fullscreen mode Exit fullscreen mode

It just makes sure that you can only use keys inside the breakpoints. Otherwise, it throws an error.


You can get the code from GitHub repo.

If you've liked this article, please do consider sharing with others. It means the world to me.


That's it! I hope you liked it!

. . . . . . . . . . . . . . . . . .
Terabox Video Player