SASS – mixin for responsive design

In this post, I am going to explain how to use SASS mixin for responsive design which is very powerful way.

In CSS, there is a media query you can use to present a different layout for different screen size. However, it would be very tedious to write media query break points in every CSS component you write. What if screen size changes for a phone or tablet? You probably do not want to go through everything to fix it. There needs to be a better way to handle different screen size flexibly and let’s take a look at each option

mixin directive

what is mixin? It is a directive and lets you create CSS code that is to be reused throughout the website. It’s basically like a function in different programming languages.

Let’s first define each breakpoints. These are the breakpoints I want to be able to handle.

0 - 600px: phone
600 - 900px: Tablet portrait
900 - 1200px: Tablet landscape
[1200-1800] is where our normal styles apply
1800px + : Big Desktop

Use mixin directive – option 1

We are going to create a mixin called respond-phone so that you can just include the mixin in each component/layout for phone.
Please note that @content directive allows to pass in a block of code to mixin.

// _mixins.scss
@mixin respond-phone {
    // content directive allows to pass in a block of code to mixin
    @media (max-width: 600px) { @content };
}

// _base.scss
html {
    font-size: 62.5%;
    
    @include respond-phone {
        font-size: 50%;
    }
}

Originally, the font size is 62.5% of the root font size. However, by using the respond-phone mixin, it changes to 50%. It is pretty convenient because you don’t need to hard code media query every place. Instead, you just need to create necessary mixin functions (i.e., respond-tablet-portrait, respond-tablet-landscape) and use it. Although this is certainly an improvement, is there a better way? Is there a way to use just one mixin to represent all?

Use mixin directive – option 2

Since mixin is like a function, it can take an argument. It enables us to write a mixin that specifies proper media query breakpoint based on the argument!

Please note that unlike the example above, I used em instead of px. Why? It’s because if a user changes the default font size in a browser media queries will not be affected by that. However, we want the media query to reflect the change in default font size in a browser setting. Since em is a relative unit, it is the perfect one to use.

In a media query, em is always affected by the one that comes from the browser which is 16px. 1em = 16px

// _mixins.scss
/*
$breakpoint argument choices:
- phone
- tab-port
- tab-land
- big-desktop
*/
@mixin respond($breakpoint) {
  @if $breakpoint == phone {
    @media (max-width: 37.5em) { @content }; // 600px
  }
  @if $breakpoint == tab-port {
    @media (max-width: 56.25em) { @content }; // 900px
  }
  @if $breakpoint == tab-land {
    @media (max-width: 75em) { @content }; // 1200px
  }
  @if $breakpoint == big-desktop {
    @media (min-width: 112.5em) { @content }; // 1800px
  }
}

Now, we have a single mixin to use for all different screen sizes. Let’s take a look at how to use them

// _base.scss
html {
  font-size: 62.5%; // 1rem = 10px; 10 / 16 = 62.5%

  @include respond(tab-land) { // width < 900?
    font-size: 56.25%; // 1rem = 9px, 9 / 16 = 56.25%
  }

  @include respond(tab-port) { // width < 600 ?
    font-size: 50%; // 1rem = 8px, 8 / 16 = 50%
  }

  @include respond(phone) {
    font-size: 43.75%; // 1rem = 7px, 7 / 16 = 43.75%
  }

  @include respond(big-desktop) {
    font-size: 75%; // 1rem = 12px, 12/16 = 75%;
  }
}

Here, we are trying to use font-size as a breakpoint for different screen layout. You can see that I want to use different font-size for different screen and I converted to percentage to be flexible.

Please note the order of the mixin. All the max-width mixins are in a decreasing order. It’s ordered to prevent unintentional side effect. For example, if the screen size is 500px, it will fall under all the tablets and phone size. In that case, the last property written is selected and that’s why I ordered them in a decreasing size way.

Conclusion

It’s not simple to write a responsive designs due to its complexity. However, using the mixin could help a lot.

Leave a Reply

Your email address will not be published.