Responsive SASS mixin helpers

June 2, 2019

Thought I’d share some of my basic SASS mixin helpers that I use when implementing UIs.

Breakpoints

The first thing you’ll need to do is specify/configure your breakpoints. A breakpoint is defined as some kind of width value in pixels, it’s generally mapped to normal/popular device widths.

You can add more, or remove some, the only important thing is that they all need to be in an ascending order, with the smallest value first, and the largest last.

I usually go with something like this.

$breakpoints: (
    ('xs', 480px),
    ('s', 624px),
    ('sm', 768px),
    ('m', 896px),
    ('md', 1024px),
    ('l', 1195px),
    ('lg', 1366px),
)

Respond from

My respond-from mixin is used when you want something to happen from a specific device width.

This is probably the method I used the most, because it’s most compatible with a mobile-first approach in development (i.e. you start with the mobile UI, and add properties on top of it, i.e. adding properties from a width).

@mixin respond-from($media) {
     @each $breakpoint in $breakpoints {
          @if $media == nth($breakpoint, 1) {
               @media (min-width: #{nth($breakpoint, 2)})  { @content; }
          }
     }
}

Respond to

The respond-to mixin only responds to specific sizes, the size that you sent in as an argument all the way until the next breakpoint. I.e. @include respond-to(m) would only respond from device width of 896px until 1023px.

I generally use this if I need to hack something, or quickly add something to a very specific thing. I generally never use this function, although it’s good to have when you need it.

@mixin respond-to($media) {
    @for $i from 1 through length($breakpoints) {
        $breakpoint: nth($breakpoints, $i);
        $name: nth($breakpoint, 1);
        $value: nth($breakpoint, 2);

        @if $media == $name {
            @if $i == 1 {
                @media (max-width: #{$value})  { @content; }
            } @else if $i == length($breakpoints) {
                @media (min-width: #{$value})  { @content; }
            } @else {
                $next_breakpoint: nth($breakpoints, $i + 1);
                $next_name: nth($next_breakpoint, 1);
                $next_value: nth($next_breakpoint, 2);

                @media (min-width: #{$value}) and (max-width: #{$next_value - 1px}) { @content; }
            }
        }
   }
}

Respond until

My last mixin is the respond-until, which is the same as respond-from, but inverse.

In some cases you don’t want to override options for larger devices, you just want them to fallback to whatever is native defaults. In those cases you can either use respond-to and apply it to all specific widths, which is laborious and ends up with a lot of duplicate code, the other alternative is respond-until, which will match until the width value is met.

@mixin respond-until($media) {
     @each $breakpoint in $breakpoints {
          @if $media == nth($breakpoint, 1) {
               @media (max-width: #{nth($breakpoint, 2)})  { @content; }
          }
     }
}

Usage

The following code will make the element .my-header have a red background until the sm breakpoint. It will then turn orange until the device width is at (or is larger than) the m breakpoint.

.my-header {
    @include respond-until(sm) {
        background: red;
    }
    @include respond-to(sm) {
        background: orange;
    }
    @include respond-from(m) {
        background: green;
    }
}

These mixins are fairly simple, but they’ve been extremely useful for me these last couple of years.

Tags