Media Queries with Sass Mixins and Maps
Tags: sass, mixins, maps
Published: 2022-08-12 15:06:00

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`
```scss
@mixin mq() {
   @media only screen and (min-width: 50em) {
     @content;
  }
}
```

If you have tried this out in the main file:

`style.scss`
```scss
@use 'media-query' as *;

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

  @include mq() {
    --fs-400: 1.125rem;
  }
}
```

Compiled CSS should look like this:

`style.css`
```css
:root {
  --fs-400: 1rem;
}

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

---

### Stage II

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

`_media-query.scss`
```scss
@mixin mq($size) {
   @media only screen and (min-width: $size) {
     @content;
  }
}
```

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

`style.scss`
```scss
@use 'media-query' as *;

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

  @include mq(50em) {
    --fs-400: 1.125rem;
  }
}
```

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`
```scss
$breakpoints: (
  sm: 30em,
  md: 50em,
  lg: 75em,
);
```

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`
```scss
$breakpoints: (
  sm: 30em,
  md: 50em,
  lg: 75em,
);

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

  @media only screen and (min-width: $size) {
    @content;
  }
}
```

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

`style.scss`
```scss
@use 'media-query' as *;

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

  @include mq('md') {
    --fs-400: 1.125rem;
  }
}
```

> **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`
```css
:root {
  --fs-400: 1rem;
}

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

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

`_media-query.scss`
```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';
  }
}
```

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](https://github.com/dostonnabotov/frontend-guide/tree/main/sass/media-query).

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!