Search code examples
sassbreakpointsmixinsscss-mixinsbreakpoint-sass

SASS Mixin Help - Breakpoint


Trying to customize the following SASS mixin. Right now it is creating the same set of CSS for each breakpoint, however, when I get to the "sm" and "xs" breakpoints I want the mixin to alter the code slightly (see alteration below code).

$columns: 12;
$gutter: 40px;
$margin: 20px;
$max-width: 100%;

$breakpoints: lg 1199.98px 1200px,
md 991.98px 992px,
sm 767.98px 778px,
xs 575.98px 576px !default;

@each $breakpoint in $breakpoints {
  $name: nth($breakpoint, 1);
  $size: nth($breakpoint, 2);
  $container: nth($breakpoint, 3);

  @media only screen and (max-width: $size) {
    .container {
      max-width: $container;
    }

    @for $i from 1 through $columns {
      .col-#{$name}-#{$i} {
        flex-basis: calc((100% / #{$columns} * #{$i}) - #{$gutter});
        max-width: calc((100% / #{$columns} * #{$i}) - #{$gutter});

        &.fluid {
          flex-basis: calc(100% / #{$columns} * #{$i});
          max-width: calc(100% / #{$columns} * #{$i});
          margin-left: 0;
          margin-right: 0;
        }
      }
    }
  }
}

At the "sm" breakpoints I want it to alter the formula to read ...

flex-basis: calc((100% / #{$columns} * #{$i}) - (#{$gutter} / 2));
max-width: calc((100% / #{$columns} * #{$i}) - (#{$gutter} / 2));

At the "xs" breakpoints I want it to alter the formula to read ...

flex-basis: calc((100% / #{$columns} * #{$i}) - (#{$gutter} / 3));
max-width: calc((100% / #{$columns} * #{$i}) - (#{$gutter} / 3));

Solution

  • The easiest solution would be to pass a gutter value as parameter in your @each directive.
    But, you might want to keep a global gutter value, so here is an alternative:

    First, you could shorten this:

    @each $breakpoint in $breakpoints {
      $name: nth($breakpoint, 1);
      $size: nth($breakpoint, 2);
      $container: nth($breakpoint, 3);
      // ...
    }
    

    By this:

    @each $name, $size, $container in $breakpoints {
      // ...
    }
    

    Then, you will need to add a new value to your list. It will be used to divide the gutter value.
    Note that your list is totally valid, but I would suggest to use the following format which is far more readable.

    $breakpoints: (
      (lg, 1199.98px, 1200px, 1),
      (md, 991.98px, 992px, 1),
      (sm, 767.98px, 778px, 2),
      (xs, 575.98px, 576px, 3)
    ) !default;
    

    You can now include this new value as parameter:

    @each $name, $size, $container, $divide in $breakpoints {
      // ...
    }
    

    And use it like this:

    flex-basis: calc((100% / #{$columns} * #{$i}) - #{$gutter} / #{$divide});
    max-width: calc((100% / #{$columns} * #{$i}) - #{$gutter} / #{$divide});
    

    You can see the full code here.