Search code examples
cssresponsive-designsasssusy-sassbreakpoint-sass

susy proper way to switch grid settings in breakpoint


I am attempting to define some default behaviors for a grid and then override them at specific breakpoints. In the following example I would like the two divs to be stacked on top of each other, with slightly modified gutter settings from the default, and then at 800px and above I would like the divs to stack next to each other. The second part does not happen. Seems like some margin settings from the less than 800px scenario are being applied to the greater than 800px scenario. Please let me know how to code this and adhere to susy best practices.

HTML:

<div class="container">
    <div class="primary">
        <p>I am Primary</p>
    </div>
    <div class="secondary">
        <p>I am Secondary</p>
    </div>
</div>

SCSS:

$susy:
(
  flow: ltr,
  output: float,
  math: fluid,
  column-width: false,
  container: 1200px,
  container-position: center,
  last-flow: to, columns: 12,
  gutters: 1 / 4,
  gutter-position: after,
  global-box-sizing: border-box,
  debug: (
    image: hide,
    color: rgba(#66f, 0.25),
    spot: background, toggle: bottom right)
  );

* {
    @include box-sizing(border-box);
}

.container{
    @include container;
}

.primary{
    background-color: red;
}

.secondary{
    background-color: blue;
}

// Mobile first layout with slightly different
// gutter settings from default
@include with-layout(12 0.5 split){

    .primary{
        @include span(12);
    }

    .secondary{
        @include span(12);
    }
}

// this layout should take over at 800px and above
// and share a row but instead boxes end up on different
// rows
@include susy-breakpoint(800px, $susy)
{
    .primary{
        @include span(first 6);
    }

    .secondary{
        @include span(last 6);
    }
}

I also made a codepen example that can be found here:

http://codepen.io/sbonham/pen/vLKvMJ


Solution

  • Yep, Susy is just writing CSS values, so you have to handle this the same way you would with plain CSS. Susy doesn't know your DOM, so it has no way of knowing that you want to override values that you set before. If we assumed you always want to override, we would have to output massively bloated code.

    There are two solutions here:

    • Put your small-screen layout inside a max-width media-query, so it doesn't affect larger screens.
    • Or: override those global values inside the large-screen media-query. The problem to fix is the extra margins added by your initial split gutters.

    I prefer the first solution, because I think overrides are ugly. But if you're dealing with some small browsers that doesn't support media-queries (do those still exist?), then you'll need to use the second solution. Try:

    @include susy-breakpoint(max-width 800px, 12 0.5 split) {
        .primary{
            @include span(12);
        }
    
        .secondary{
            @include span(12);
        }
    }