For a while now, I’ve been using Susy, a Sass grid framework, to build layouts in CSS. I’m a big fan of Susy as, unlike traditional CSS frameworks, it allows you to separate markup from style. (This article I wrote for Smashing Magazine explains further.)

Recently I’ve been using flexbox quite a bit for smaller UI components, and it got me thinking about how I could combine these two for super-charged layout creation.

Flexbox

Flexbox has some really fantastic and useful features that free us from the constraints of using floats in CSS: You can align items left, right or center, on a horizontal or vertical(!) axis, equally space your items (using the justify-content property) and easily create equal-height columns. Awesome!

The downside? Flexbox isn’t the perfect tool for building entire page layouts – it’s better suited to smaller chunks of UI. It doesn’t do any calculations for you, so if you want, say, an area of content to span 7 columns of its parent and a second element to span 3 columns, you need to calculate the column widths yourself – not necessarily a problem when dealing with simple numbers, but when you factor in gutters and varying numbers of columns, it becomes more difficult to keep things consistent.

The Grid Layout Module (currently in working draft) goes further than ever before towards an ideal layout solution for CSS, but it’ll be a while before we see widespread browser support.

Susy

Susy is a great timesaver when coding layouts, as it does the maths for you. Specify the number of columns and the gutter width (or ratio) you want at the beginning, then simply call on Susy’s span mixins to map out your grid.

  main {
    @include span(8);
}

If my layout is 12 columns wide, the above mixin tells Susy that my main element should span 8 columns out of 12.

However, Susy still relies on floats, meaning you need to remember to put clearfixes on any parent element with floated children. Inevitably it lacks many of the properties that makes flexbox so appealing. That’s how I ended up combining the two in my most recent work…

Flexbox + Susy = Magic Layouts!

As well as mixins, Susy allows crucial properties to be used as functions. So while

  main {
    @include span(8);
}

will be outputted in CSS as:

  main {
  width: 66.10169%;
  float: left;
  margin-right: 1.69492%;
}

using span as a function, as below, will output only the width, ignoring the float and margin properties:

  main {
    width: span(8);
}

compiles to:

  main {
  width: 66.10169%;
}

If we want columns, side-by-side, with equal gutter widths (no matter how many columns, or how wide each column), we can set these flexbox properties on our parent element:

  .wrapper {
    display: flex;
    justify-content: space-between;
}

Then specify our column widths:

  .wrapper {
  .col-1 {
    width: span(3);
  }
  .col-2 {
    width: span(5);
  }
  .col-3 {
    width: span(4);
  }
}

Here’s one I made earlier:

If your items add up to more columns than the number available (12), they’ll simply reflow to the next line – no need to remove margins with :nth-child, because we aren’t using any.

We can also use Susy’s gutter function to set a bottom margin equal to the gutter:

  .col {
    margin-bottom: gutter();
}

Alternatively, we could group our items into rows and set the bottom margin for each row.

There is one caveat with this method: If your items do not span all columns in a row, then using justify-content: space-between will not give you equal gutters (because this flexbox property spaces all your items equally). If you want to leave an empty column in the middle of a row, for instance, it would be better to omit this property use margins to set your column gutters (e.g. margin-right: gutter();). This means, of course you’ll need to remove the right margin from your final element in a row, but because we’re not floating elements you don’t need to worry about clearfixes.

Despite this, I still find it very useful to use Susy’s maths combined with flexbox – far quicker and easier than calculating my own column and gutter widths.

If you have any thoughts about this, or any other layout tools or methods, I’d love to hear from you! To see this method in action on a live project, check out this portfolio site I made recently: http://michellebarker.co.uk.