Menu Search
Jump to the content X X
Smashing Conf New York

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Website Layout Tools Compared: Flexbox Vs. Susy

Flexbox has become one of the most popular tools for creating website layouts. Susy is another layout tool that has gained popularity with the Sass community over the last few years.

Many developers I’ve spoken with are unsure which tool is best for creating layouts for their websites. Some feel that flexbox is powerful enough to handle all of their layout problems. However, they are unsure whether to learn it because of its confusing syntax. Others feel that Susy is much simpler and prefer its simplicity to flexbox.

Some even ask whether combining Susy and flexbox is possible so that they can make layouts much more easily. So, these are the two questions that this article seeks to answer:

  1. Which is more powerful, flexbox or Susy?
  2. Is it possible to use both flexbox and Susy at the same time?

Let’s get the ball rolling by looking at how we’re going to compare flexbox and Susy.

How We Are Comparing Flexbox And Susy

Strictly speaking, it’s impossible to compare flexbox and Susy directly because they are two completely different tools. It would be more appropriate to compare flexbox with a float-based layout.

However, because both Susy and flexbox are used to build layouts, we can try to build different layouts to serve as a proxy for comparison. In this article, we’ll compare five layouts:

  1. content and sidebar layout
  2. content and sidebar on a proportional grid
  3. content and sidebar on a fixed-gutter grid
  4. gallery layout on a proportional grid
  5. gallery layout on a fixed-gutter grid

Don’t worry if you’re unsure what a proportional or fixed-gutter grid is. We’ll get to that when we cover the second layout.

For now, let’s start the comparison with layout 1.

Layout 1: Content And Sidebar Layout

In this first layout, we want to keep things simple so that you start getting used to creating grids with both flexbox and Susy.

Here, we’re going to create a blog-like layout similar to Smashing Magazine’s, where the content takes up 75% of the total width, while the sidebar takes up 25% of the total width:

content-sidebar-layout1
A blog-like content and sidebar layout. (View large version2)

Here’s the markup we’re using for both flexbox and Susy for this layout. We have a containing element plus two divs for each tool.

<!-- Flexbox markup -->
<div class="flexbox">
  <div class="content"> <h4> Content </h4> </div>
  <div class="sidebar"> <h4> Sidebar </h4> </div>
</div>

<!-- Susy markup -->
<div class="susy">
  <div class="content"> <h4> Content </h4> </div>
  <div class="sidebar"> <h4> Sidebar </h4> </div>
</div>

As you can see, we’re keeping things consistent by using the same markup.

Now, let’s start styling.

Flexbox

With flexbox, we first need to give the parent container (.flexbox) a display property of flex.

Note: We’re skipping the vendor prefixes to simplify the code.

.flexbox {
  display: flex;
}

Then, we add flex-basis, which is similar to the width property, to .content and .sidebar.

.flexbox {
  display: flex;
  .content { flex-basis: 75%; }
  .sidebar { flex-basis: 25%; }
}

See the Pen YywXoj3 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Susy Link

Susy comes with a default gutter setting on the grids. We first have to disable it by setting gutters to 0 in the $susy map:

// Importing Susy
@import "susy";

// Removing default gutters
$susy: (
  gutters: 0
);

The most common way of using susy so far is with the span() mixin. Here, we can use percentages in the span() mixin for both .content and .sidebar to achieve a similar result:

.susy {
  .content { @include span(75%); }
  .sidebar { @include span(25%); }
}

Because Susy defaults to a float-based layout, we need to force the parent element (.susy) to clear its child elements to prevent the parent element from collapsing6:

@mixin clearfix {
  &:after {
    content: ' ';
    display: table;
    clear: both;
  }
}

.susy {
  // Adds clearfix
  @include clearfix;
  .content { @include span(75%); }
  .sidebar { @include span(25%); }
}

See the Pen meevdq7 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

As you can see, the code for both Susy and flexbox are incredibly similar at this stage. The only difference we can point out right now is that flexbox works purely with CSS, whereas Susy requires the Sass preprocessor.

Let’s move on and compare the next layout. It’ll make things much more interesting.

Layout 2: Content And Sidebar On A Proportional Grid

We’re going to compare a layout with a grid because grids are a basic building block on the web for both designers and developers.

When we think of building a grid for the web, we immediately have to think about how the grid will respond to different screen widths.

Should the columns and gutters expand proportionally when the grid scales upward (a proportional grid)?

proportional-grids10
Proportional grid. (View large version11)

Or, should the gutters remain at a fixed size as the columns expand (a fixed-gutter grid)?

Fixed-gutter grid12
Fixed-gutter grid. (View large version13)

The question is important to consider because it will affect how the layout responds on a fluid medium like the web. It will also affect how the layout is coded.

Let’s explore proportional grids first.

Before moving on, let’s use Susy to help us create a background for the grid so that we can easily see whether we’re on the right track. For this example, we’re going to use a twelve-column grid, and the width of each column will be four times the width of each gutter.

$susy: (
  columns: 12, 
  gutters: 0.25,
  debug: (image: show-columns)
);

Then, we’ll show the grid on both .flexbox and .susy with the show-grid() mixin that Susy provides. This show-grid() mixin only creates a background image on the selector and doesn’t affect the code in any way.

.flexbox, 
.susy {
  @include show-grid(8);
}

All right, let’s move on. For this layout, let’s try making .content take up nine columns of the grid, while making .sidebar take up the remaining three columns.

Because we’re working on a proportional grid, we need to use percentage widths for both the columns and gutters. Let’s try creating this layout with flexbox first.

Flexbox Link

We need to do some math because we’re using percentages.

For this layout, let’s assume that each gutter is 20 pixels wide. The columns are four times the gutter width — hence, 80 pixels wide.

The total width of the 12-column layout would then be (12 * 80px) + (11 * 20px) = 1180px.

Width of 12 columns14
Width of 12 columns. (View large version15)

Because .content takes up nine columns, its width should be (9 * 80px) + (8 * 20px) = 880px.

Width of nine columns16
Width of nine columns. (View large version17)

Lastly, we can calculate the percentage width by dividing the width of the content by the grid’s total width. That’s 880px ÷ 1180px * 100% = 74.58%.

Percentage width of nine columns18
Percentage width of nine columns. (View large version19)

Then, we can do the same painful math to get the width of .sidebar:

.flexbox {
  display: flex;

  .content { flex-basis: 74.5762712%; }
  .sidebar { flex-basis: 23.7288136%; }
}

Thankfully, we don’t have to do the math again for the gutters because we can set justify-content to space-between in the flex container. This is because the leftover space, which is one gutter wide, will be distributed between .content and .sidebar.

.flexbox {
  display: flex;
  justify-content: space-between;

  .content { flex-basis: 74.5762712%; }
  .sidebar { flex-basis: 23.7288136%; }
}

See the Pen jbWbPW20 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Now, let’s look at how to create the same layout with Susy.

Susy Link

With Susy, we insert the number of columns directly into the span() mixin, and it will calculate the percentage width for us. Here, .content would be span(9) because the content takes up nine columns.

Susy also automatically calculates one gutter width and adds it as margin-right to the span() mixin. Hence, when adding span() to sidebar, we have to add an extra last keyword to tell Susy to remove the margin-right property.

In short, the code to create the same layout with Susy is this:

.susy {
  @include clearfix;

  .content { @include span(9); }
  .sidebar { @include span(3 last); }
}

See the Pen avvMyK23 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Right here you might be thinking that this code is so much more elegant, with no painful math. Does this mean that Susy is better than flexbox?

Well, no. We mentioned earlier that we cannot compare flexbox and Susy directly because they are different tools. It would be more appropriate to compare flexbox with the float-based layout for which we had to calculate the painful math back in the day.

This is also where most people misunderstand Susy. It is not a framework. It’s a powerful grid calculator that’s built to handle grid math.

Because it’s just a calculator, we can also use Susy with flexbox to remove the painful math. The trick lies in a little-known feature in Susy.

This feature is the span() function. It’s what the span() mixin uses under the hood to create the width property.

So, we can also say that the flex-basis of .content is span(9) and that the flex-basis of .sidebar is span(3) to get the same result:

.flexbox {
  display: flex;
  justify-content: space-between;

  // Susy span function with flexbox
  .content { flex-basis: span(9); }
  .sidebar { flex-basis: span(3); }
}

See the Pen LppazX26 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

As you can see by now, flexbox and Susy cannot be compared directly because they are different tools. However, Susy can be used to complement flexbox for areas for which it is built: grid math.

That being said, let’s continue our “comparison” of how to build layouts with flexbox and Susy so that you can see the nitty-gritty details that many people miss out on.

Let’s move on to the third layout, where we tackle a fixed-gutter grid.

Layout 3: Content And Sidebar On A Fixed-Gutter Grid

Before continuing, let’s create a grid overlay so that we know whether we’re aligning the grids properly. In this case, we have to roll our own grid for comparison because the one provided by Susy isn’t able to work on a fixed-gutter grid.

The markup for this grid is this:

<div class="fixed-gutter-grid">
  <!-- 12 columns in total -->
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
  <div class="column"></div> 
</div>

Next, let’s find out how to create the CSS for this grid overlay.

First, gutters must be written with a fixed unit because only columns expand in size. Let’s use 20 pixels as the gutter width of this grid, according to our previous example.

There are 11 gutters in total, which means the remaining columns must make up a total width of 100% - (11 * 20px). The width of each column is, thus, (100% - (11 * 20px)) ÷ 12.

We can’t mix percentages and pixels under normal circumstances, so we need to use the calc() function to help us with that.

Here’s the full CSS for this grid:

.fixed-gutter-grid {
  @include clearfix;

  .column {
    width: calc((100% - (11 * 20px)) / 12);
    margin-right: 20px;
    float: left;
    height: 80px;
    background: rgba(blue, 0.25);

    &:last-child {
      margin-right: 0;
    }
  }
}

See the Pen Maadxe29 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Because we have the grid set up, let’s move on and try to style both .content and .sidebar. We’re striving for this:

Content and sidebar layout in a fixed-gutter grid32
Content-and-sidebar layout in a fixed-gutter grid. (View large version33)

Flexbox Link

On first thought, creating such a grid with flexbox should be easy. You’d probably think that we can add 20 pixels worth of margin between .content and .sidebar and that flexbox would magically divide the space between .content and .sidebar equally.

.flexbox {
  display: flex;
  justify-content: space-between;
  
  .content {
    flex-basis: 75%;
    margin-right: 20px;
  }
  .sidebar {
    flex-basis: 25%;
  }
}

Unfortunately, it’s not as easy as that. This is what you’d get:

Flexbox with fixed-gutter grid34
Flexbox with fixed-gutter grid. (View large version35)

It doesn’t matter if you add the margin to .content or .sidebar or split the margin between the two. The result will be the same.

This is because when we take gutters into account, .content and .sidebar are no longer at the exact ratio of 3:1. It’s impossible, then, to calculate the exact ratio between .content and .sidebar because it’s constantly changing.

There is, however, one way to circumvent this flex-basis issue. It requires three steps:

  1. Add a negative margin (left and right) to the flexbox container equal to half of the gutters.
  2. Add padding (left and right) to all flex items equal to half of the gutters.
  3. Set the border-box property for all flex items.
.flexbox {
  /* Other properties */
  margin-left: -10px;
  margin-right: -10px;

  > div {
    box-sizing: border-box;
    padding: 0 10px;
  }

  .content { flex-basis: 75%; }
  .sidebar { flex-basis: 25%; }

Well, because we’re using padding and the box-sizing property is set to border-box, we won’t be able to see any visual changes with our current CSS.

We need to give the inner content of each flex item another background color to see that it aligns to the grid:

h4 {
  background: turquoise;
}

See the Pen wKMarR36 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Here’s a problem. What if we wanted to add background-color to the flex item?

One way to solve this problem is to add extra markup, but that’s not the best way to handle it.

An alternative is to use margin instead of padding for each flex item. When we use margin, we must augment the flex-basis calculation with calc() so that it is the original flex-basis minus a full gutter width.

So, the flex-basis for the content should be calc(75% - 20px). The rest of the properties are as follows:

.flexbox {
  /* Other flexbox properties */
  margin-left: -10px;
  margin-right: -10px;

  > div {
    /* Switching to margins */
    margin: 0 10px;
  }
  
  /* flex-basis = percentage - gutters on each side */
  .content { flex-basis: calc(75% - 20px); }
  .sidebar { flex-basis: calc(25% - 20px); }
}

Here’s an additional tip: You can use the percentage function in Sass if you don’t like to calculate math like 75% or 25%.

.content { flex-basis: calc(#{percentage(3/4)} - 20px); }
.sidebar { flex-basis: calc(#{percentage(1/4)} - 20px); }

See the Pen BojNVM39 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

One more thing. Try scrolling the Codepen above to the right and you’ll see a 10-pixel gap. This gap is created when we added margin-right: -10px to .flexbox.

This is a slight nuance with flexbox on a responsive website. If you do use negative margins on a flex container, make sure to remove the extra space created by adding overflow-x:hidden to the parent element.

In this case, our parent element is body.

body {
  overflow-x: hidden;
}

See the Pen EVPVZo42 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Let’s see how Susy handles something like this.

Susy Link

Susy doesn’t have an answer for this grid because it is made to calculate percentage widths. What we can do instead is compare it with a float-based layout in which we roll our own calculations with calc().

So far, we know this:

  1. The width of one gutter is 20 pixels.
  2. The width of one column is calc(100% -(11 * 20px) ÷ 12).

From the calculations above (in layout 2), we know that the total width of nine columns is equal to (9 x column-width) plus (8 x gutter-width), which is equal to calc((100% - (11 * 20px)) * 9 ÷ 12 + 8 * 20px)

Nine columns45
Nine columns. (View large version46)

We can follow the same math to get the width of .sidebar:

.self-made-grid {
  @include clearfix;

  .content {
    float: left;
    width: calc((100% - (11 * 20px)) * 9 / 12 + 8 * 20px);
    margin-right: 20px;
  }

  .sidebar {
    float: left;
    width: calc((100% - (11 * 20px)) * 3 / 12 + 2 * 20px);
  }
}

See the Pen bVVyQP5047 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

As you can see, it gets complicated quickly if we have to do this math over and over again. One thing we can do to simplify the process is to create a grid calculator mixin:

$columns: 12;
$gutter: 20px;

@mixin custom-span($span) {
  float: left; 
  width: calc((100% - (#{($columns - 1)} * 20px)) * #{$span} / 12 + #{($span - 1)} * 20px);
  margin-right: $gutter;
}

.self-made-grid {
  @include clearfix;

  .content { 
    @include custom-span(9); 
  }
  .sidebar {
    @include custom-span(3);
    margin-right: 0;
  }
}

See the Pen bVVyQP5047 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Not too difficult to roll our own math calculator, is it?

Anyway, let’s get back on topic.

As you can see, we need to do some weird tweaking with flexbox to get it to work properly with a fixed-gutter grid. Once you get the basics down, creating any kind of layout with this type of grids should be simple.

Note that this method is incredibly important (and you’ll see why in layouts 4 and 5).

Layout 4: Gallery Layout On A Proportional Grid

In addition to normal content-and-sidebar layouts, the other layout we normally find ourselves creating is a gallery.

Let’s try to make a three-by-three gallery.

Three by three gallery53
Three-by-three gallery. (View large version54)

Because we’re creating a gallery, our markup must change slightly.

<div class="flexbox">
  <!-- 9 gallery__items -->
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
  <div class="gallery__item">item</div>
</div>

Likewise, we have to consider both types of grids. Let’s find out how to create a gallery on a proportional grid first.

Flexbox Link

The first thing you’ll notice is that there is more than one row of items. When this happens, we need to give .flexbox a flex-wrap property of .wrap to allow the flex items to flow to the next row.

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

Next, we need to calculate the flex-basis so that each gallery item takes up four columns exactly. We know from the math above that it should be ((4 * 80px) + (3 * 20px)) ÷ 1180px * 100% = 32.20339%.

.gallery__item {
  flex-basis: 32.20339%;
}

We also learned above that we can switch this math out with a Susy span() function:

.gallery__item {
  flex-basis: span(4);
}

What we have now is this:

Incomplete flexbox gallery layout55
Incomplete flexbox gallery layout. (View large version56)

When we create a gallery, we usually add vertical margins so that the vertical and horizontal spaces between gallery items are equal.

The first thought that will probably come to your mind is that we can add a percentage-based margin-top property to each gallery item. This margin-top should be equal to the width of one gutter.

This width would be 20 ÷ 1180 * 100% = 1.694915254%. Alternatively, we can get it with Susy’s gutter() function:

 .gallery__item {
    flex-basis: span(4);
    margin-top: gutter();
  }

If you remove the background grid, you’ll have an equal-spaced gallery:

See the Pen Gppabz57 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

… That is, until you use Firefox to view this layout:

Percentage margin trick fails in Firefox60
Percentage margin trick fails in Firefox. (View large version61)

This margin-top trick fails because the flex item’s margin and padding percentages are supposed to resolve against the flex container’s explicit size, according to the flexbox specification62.

This means that percentage values for margin-top will be calculated only if we state a height value for the flex container. Because we didn’t do so, margin-top would be equal to zero instead.

This method fails in Firefox because only Firefox has implemented the part of the specification we just mentioned. Neither WebKit nor Internet Explorer have implemented it yet.

This brings us to an unfortunate conclusion: Creating a percentage-based gallery with flexbox is impossible if we want to ensure that the vertical and horizontal spaces are equal. We can, however, still use absolute units (like px and em) for vertical spaces if we’re not going for a perfectly equal-spaced grid.

Let’s look at how we’d tackle a gallery layout with Susy next.

Susy Link

Susy provides us with a gallery() mixin that can be used to create a gallery. All we need to do is add the number of columns each gallery item would take up in the gallery() mixin.

.susy {
  @include clearfix;

  .gallery__item {
    @include gallery(4);
  }
}

Because Susy uses a float-based layout, we can stick to using a percentage-based margin to create an equal-spaced gallery without any problem:

.susy {
  @include clearfix;

  .gallery__item {
    @include gallery(4);
    margin-top: gutter();
  }
}

See the Pen VveZKz63 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

As you can see, the only way to produce a gallery with percentage-based widths is through a float-based layout.

However, if we stick to a float-based layout, we won’t be able to handle gallery items of unequal heights:

A float-based layout cannot handle a gallery with unequal height66
Float-based layouts cannot handle a gallery with unequal heights. (View large version67)

We need to switch to the fixed-width grid to create such a gallery because we need to use the align-stretch property that flexbox provides.

So, let’s move on to layout 5, where we’ll find out how to create this gallery with flexbox.

Layout 5: Gallery Layout On A Fixed-Gutter Grid

For this final layout, let’s cut the chatter and jump right to creating the gallery with flexbox.

Flexbox Link

We can use the same principles in layout 3 (content and sidebar on a fixed-gutter grid) to create a gallery.

Once again, we need to do the following:

  1. Add a negative margin (left and right) to the flexbox container equal to half of the gutters.
  2. Add margin to all flex items equal to half of the gutters.
  3. Use calc() on all flex-basis items.
  4. Set overflow-x to hidden on flexbox’s parent container.
body {
  overflow-x: hidden;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin-left: -10px;
  margin-right: -10px;

  > div {
    margin: 0 10px;
  }

  .gallery__item {
    flex-basis: calc(#{percentage(1/3)} - 20px);
    margin: 10px;
  }
}

The good thing about this gallery is that it takes care of items with unequal heights, freeing you from having to worry about it:

See the Pen YywrGQ68 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

We’re not going to talk about Susy with the fixed-gutter layout because we know we’re just going to roll our own solution again.

For the next part, because we’re on the topic of galleries, let’s talk about how to deal with two scenarios that always happen with galleries:

  1. gallery items of unequal width,
  2. leftover items in a gallery.

Let’s tackle these questions with both flexbox and Susy. The difference, though, is that we’re going to compare flexbox for layout 5 with Susy for layout 4 to show how to deal with these situations.

Dealing With Items Of Unequal Width In Flexbox

Let’s say we want the first item in a gallery to be twice the size of other gallery items.

Flexbox Link

We just have to make a simple adjustment to flexbox, increasing the flex-basis percentage so that it’s twice the width of the rest of the items:

.gallery__item:first-child {
  flex-basis: calc( #{percentage(2/3)} - 20px);
}

See the Pen YywrNx71 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

Susy Link

It’s not as easy with Susy because it uses the isolate technique to create galleries. You’ll get an overlapping element if you tried the method we used with flexbox (i.e. increasing the width of the first item).

Overlapping items on a grid74

Overlapping items on a grid. (View large version75)

What we have to do is create our own gallery by understanding how nth-child and the isolate technique work. If you’re interested, check out my guest post on CSS-Tricks76 to understand how the isolate technique works.

.susy {
  @include clearfix;
  .gallery__item {
    float: left;
    width: span(4);
    margin-right: -100%;
    margin-top: gutter();
  }
  
  .gallery__item:first-child {
    width: span(8);
  }
  
  .gallery__item:nth-child(3n-1) {
    margin-left: span( 8 wide);
  }  
  
  .gallery__item:nth-child(3n) {
    clear: left;
  }
  
  .gallery__item:nth-child(3n+4) {
    margin-left: span(4 wide);
  }
}

See the Pen jbWGwR77 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

As you can see, changing the default size of gallery items with Susy is not easy. However, if you understand how Susy works, you can switch the way it handles gutters to inside or split, and you can achieve the same simplicity by using the span() mixin:

$susy: (
  // Other properties
  gutter-position: split,
);

.susy {
  @include clearfix;
  .gallery__item {
    @include span(4);
    margin-top: gutter() * 2;
  }
  
  .gallery__item:first-child {
    width: span(8);
  }
}

See the Pen ZbQXXY80 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

In the end, both methods work out to be about the same.

Let’s talk about dealing with leftover items next.

Dealing With Leftover Items

We saw how flexbox and Susy handle the one leftover item by dangling it to the left. What happens if more than one item is left over?

Flexbox Link

It’s pretty bad with flexbox because we’re using the space-between property.

Dangling items on flexbox83
Dangling items on flexbox. (View large version84)

However, we can fix it easily by setting the flex-grow property of each item to 1:

.gallery__item {
  // Other properties
  flex-grow: 1;
}

See the Pen WQrZpL85 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

This, however, will make the first item stretch the full width, so you might want to note how many items you leave dangling.

Leftover item taking up the full width88
Leftover item taking up the full width. (View large version89)

Susy Link

Susy leaves all elements hanging to the left by default, which is what most float-based layouts do.

leftoveritems-hanging-left90
Leftover items hang to the left of the grid with float-based layouts. (View large version91)

I’d recommend leaving it this way if you don’t want to mess around with a lot of code.

But just for your information, it’s possible to create a layout with a Susy gallery that has the same result as setting flex-grow: 1.

I’m not going to explain how it works because it’s rather in depth. Instead, I’ll leave you with a Codepen if you’re interested in figuring this one out yourself:

See the Pen qObPLX92 by Zell Liew (@zellwk938681787269645851484340373027242184) on CodePen948782797370655952494441383128252295.

A Final Note On Flexbox Link

We’ve only managed to discuss the flex-basis property in flexbox for this article. Flexbox provides additional properties, such as flex-grow and flex-shrink, which enable us to make interesting layouts that were impossible to do with a grid previously.

These types of layouts are beyond the scope of this article, so I highly encourage you to check out one of the flexbox courses mentioned in the next section.

Wrapping Up

We’ve covered a lot of things about building layouts with flexbox and Susy.

By this point, you’ll understand that we can’t compare flexbox and Susy directly because they are two different tools.

In addition, you’ll understand how to create different layouts with Susy and flexbox, and you’ll be able to solve most challenges that people face with both tools.

Of course, that’s not everything to know about flexbox nor Susy. There’s a whole lot more.

Here are some resources I recommend:

That’s it for the article. Let me know in the comments below how you feel having read it! Oh, and feel free to contact me if you have any questions about flexbox or Susy. I’d be happy to reply!

(rb, ml, al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/wp-content/uploads/2015/10/content-sidebar-layout-opt.png
  2. 2 https://www.smashingmagazine.com/wp-content/uploads/2015/10/content-sidebar-layout-opt.png
  3. 3 'http://codepen.io/zellwk/pen/YywXoj/'
  4. 4 'http://codepen.io/zellwk'
  5. 5 'http://codepen.io'
  6. 6 https://css-tricks.com/all-about-floats/
  7. 7 'http://codepen.io/zellwk/pen/meevdq/'
  8. 8 'http://codepen.io/zellwk'
  9. 9 'http://codepen.io'
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2015/10/proportional-grids.gif
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2015/10/proportional-grids.gif
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2015/10/fixed-gutters.gif
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2015/10/fixed-gutters.gif
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-twelve-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-twelve-opt.png
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-nine-opt.png
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-nine-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-percentage-opt.png
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2015/10/math-percentage-opt.png
  20. 20 'http://codepen.io/zellwk/pen/jbWbPW/'
  21. 21 'http://codepen.io/zellwk'
  22. 22 'http://codepen.io'
  23. 23 'http://codepen.io/zellwk/pen/avvMyK/'
  24. 24 'http://codepen.io/zellwk'
  25. 25 'http://codepen.io'
  26. 26 'http://codepen.io/zellwk/pen/LppazX/'
  27. 27 'http://codepen.io/zellwk'
  28. 28 'http://codepen.io'
  29. 29 'http://codepen.io/zellwk/pen/Maadxe/'
  30. 30 'http://codepen.io/zellwk'
  31. 31 'http://codepen.io'
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2015/10/content-sidebar-fixed-gutter-grid-opt.png
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2015/10/content-sidebar-fixed-gutter-grid-opt.png
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2015/10/flexbox-fixed-gutter-grid-opt.png
  35. 35 https://www.smashingmagazine.com/wp-content/uploads/2015/10/flexbox-fixed-gutter-grid-opt.png
  36. 36 'http://codepen.io/zellwk/pen/wKMarR/'
  37. 37 'http://codepen.io/zellwk'
  38. 38 'http://codepen.io'
  39. 39 'http://codepen.io/zellwk/pen/BojNVM/'
  40. 40 'http://codepen.io/zellwk'
  41. 41 'http://codepen.io'
  42. 42 'http://codepen.io/zellwk/pen/EVPVZo/'
  43. 43 'http://codepen.io/zellwk'
  44. 44 'http://codepen.io'
  45. 45 https://www.smashingmagazine.com/wp-content/uploads/2015/10/nine-columns-opt.png
  46. 46 https://www.smashingmagazine.com/wp-content/uploads/2015/10/nine-columns-opt.png
  47. 47 'http://codepen.io/zellwk/pen/bVVyQP/'
  48. 48 'http://codepen.io/zellwk'
  49. 49 'http://codepen.io'
  50. 50 'http://codepen.io/zellwk/pen/bVVyQP/'
  51. 51 'http://codepen.io/zellwk'
  52. 52 'http://codepen.io'
  53. 53 https://www.smashingmagazine.com/wp-content/uploads/2015/10/3x3-gallery-opt.png
  54. 54 https://www.smashingmagazine.com/wp-content/uploads/2015/10/3x3-gallery-opt.png
  55. 55 https://www.smashingmagazine.com/wp-content/uploads/2015/10/flexbox-layout4-incomplete-opt.png
  56. 56 https://www.smashingmagazine.com/wp-content/uploads/2015/10/flexbox-layout4-incomplete-opt.png
  57. 57 'http://codepen.io/zellwk/pen/Gppabz/'
  58. 58 'http://codepen.io/zellwk'
  59. 59 'http://codepen.io'
  60. 60 https://www.smashingmagazine.com/wp-content/uploads/2015/10/gallery-trick-failed-on-firefox-opt.png
  61. 61 https://www.smashingmagazine.com/wp-content/uploads/2015/10/gallery-trick-failed-on-firefox-opt.png
  62. 62 http://www.w3.org/TR/css-flexbox-1/
  63. 63 'http://codepen.io/zellwk/pen/VveZKz/'
  64. 64 'http://codepen.io/zellwk'
  65. 65 'http://codepen.io'
  66. 66 https://www.smashingmagazine.com/wp-content/uploads/2015/10/gallery-unequal-height-opt.png
  67. 67 https://www.smashingmagazine.com/wp-content/uploads/2015/10/gallery-unequal-height-opt.png
  68. 68 'http://codepen.io/zellwk/pen/YywrGQ/'
  69. 69 'http://codepen.io/zellwk'
  70. 70 'http://codepen.io'
  71. 71 'http://codepen.io/zellwk/pen/YywrNx/'
  72. 72 'http://codepen.io/zellwk'
  73. 73 'http://codepen.io'
  74. 74 https://www.smashingmagazine.com/wp-content/uploads/2015/10/overlapping-elements-opt.png
  75. 75 https://www.smashingmagazine.com/wp-content/uploads/2015/10/overlapping-elements-opt.png
  76. 76 https://css-tricks.com/build-web-layouts-easily-susy/
  77. 77 'http://codepen.io/zellwk/pen/jbWGwR/'
  78. 78 'http://codepen.io/zellwk'
  79. 79 'http://codepen.io'
  80. 80 'http://codepen.io/zellwk/pen/ZbQXXY/'
  81. 81 'http://codepen.io/zellwk'
  82. 82 'http://codepen.io'
  83. 83 https://www.smashingmagazine.com/wp-content/uploads/2015/10/dangling-items-on-flexbox-opt.png
  84. 84 https://www.smashingmagazine.com/wp-content/uploads/2015/10/dangling-items-on-flexbox-opt.png
  85. 85 'http://codepen.io/zellwk/pen/WQrZpL/'
  86. 86 'http://codepen.io/zellwk'
  87. 87 'http://codepen.io'
  88. 88 https://www.smashingmagazine.com/wp-content/uploads/2015/10/full-width-leftover-item-opt.png
  89. 89 https://www.smashingmagazine.com/wp-content/uploads/2015/10/full-width-leftover-item-opt.png
  90. 90 https://www.smashingmagazine.com/wp-content/uploads/2015/10/leftoveritems-hanging-left-opt.png
  91. 91 https://www.smashingmagazine.com/wp-content/uploads/2015/10/leftoveritems-hanging-left-opt.png
  92. 92 'http://codepen.io/zellwk/pen/qObPLX/'
  93. 93 'http://codepen.io/zellwk'
  94. 94 'http://codepen.io'
  95. 95 http://flexbox.io
  96. 96 https://twitter.com/wesbos
  97. 97 https://unravelingflexbox.com
  98. 98 https://twitter.com/LandonSchropp
  99. 99 https://twitter.com/zellwk
SmashingConf New York

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Zell is a freelance web developer based in Singapore. He loves working on the web so much that he spends all his free time diving deep into tools and frameworks to find out the best ways to work with them. He then shares everything he learned on his blog. He also authored Learning Susy and Automating Your Workflow with Gulp.

  1. 1

    Would it be worth mentioning that — according to Can I use? — flexbox is unsupported in IE9 and below, and only partially supported or buggy in IE10, IE11 and older Android browsers?

    The Susy solution uses the more established float classes, which may be more reliable on older browsers.

    6
    • 2

      Maybe it used to be relevant, but it doesn’t seem to be, anymore, unless you build in the artificial pause (or, similarly, add a whole column of your site dynamically (not just its content). Try Jake’s “normal” Demo and throttle the speed in your browser’s devtools to GPRS: it will take a few seconds to load the image, but the layout will be correct right from the start.

      0
    • 4

      This helps with old versions of IE and Flexbox: https://github.com/10up/flexibility

      1
  2. 5

    George Birbilis

    December 14, 2015 6:07 pm

    Just love XAML when I see all this mess

    -2
  3. 6

    Sean McCambridge

    December 14, 2015 8:03 pm

    This is a detailed and well documented comparison. But really, you’re merging two separate ideas: 1. flexbox vs float layout and 2. using a framework like Susy for generating float layout styles efficiently. I’m looking forward to a good detail of a Susy-like framework to generate flexbox code that handles the pitfalls you describe.

    2
    • 7

      Great question, Sean.

      Once you understand the pitfalls regarding Flexbox code, you can generate your own mixins to counter them. No need to rely on someone else to generate a framework for you.

      Besides, each framework (probably) have their own idiosyncrasies that you’ll have to wrestle and fix. Basically, we’re talking about a vanilla vs framework solution, which is totally open to debate.

      1
  4. 8

    James Steinbach

    December 14, 2015 8:32 pm

    The problem you noted with the fixed-gutter grid in flexbox (mis-aligned gutter) can be fixed by tweaking the flex-shrink property for the content & sidebar elements: http://codepen.io/jdsteinbach/pen/LGpwNy

    2
    • 9

      I see what you did there, James. Totally blew my mind!

      Quick question: How did you come out with the 1:9 ratio for flex-shrink?

      3
      • 10

        James Steinbach

        December 15, 2015 5:38 pm

        I wish I had a good answer: I changed the number till it matched :/

        5
        • 11
        • 12

          To use flex-shrink for this sounds cool but not sure how this will work (but maybe there is a solution we just don’t see now). I agree 100% with Rachel Andrew but if we want to use Flexbox here we can solve this by using the following math:

          flex-basis: calc(99.9999% * #{$fraction} – (#{$gut} – #{$gut} * #{$fraction}));

          So you don’t need any negative margin or padding adjustments, just put this in a mixin and call it. This is all you need ( and you have equal hight columns and you can change the order with just including ‘flex-direction: row-reverse’ or setting any ‘order’ properties on the column elements):

          $gutter: 20px;

          .flexbox {
          display: flex;
          .content {
          @include colwidth(9/12);
          margin-right: $gutter;
          }
          .sidebar {
          @include colwidth(3/12);
          }
          }

          You even don’t need the ‘margin-right: $gutter’ when setting ‘justify-content: space-between’.

          Further more if you have open space in the row (not adding up to 12 of 12 columns) you can adjust the columns with the justify-content property to the right side or you can center the columns or space them out with ‘margin-left: auto’

          For example:
          .col1 {
          @include colwidth(3/12);
          }
          .col2 {
          @include colwidth(3/12);
          margin-left: auto;
          }
          .col3 {
          @include colwidth(3/12);
          }

          There are plenty more options you have with Flexbox. And if you need a mobile-first design set the ‘flex-direction’ to ‘column’ adjust the width to 100% and order them as you like it. On the other hand I think there will be situations you can’t solve with Flexbox but with SUSY or LOST-GRID (lost-grid works with sass, stylus or postcss)

          In general I think Flexbox’s approach is not having 100% content for the available space but less or more and use the grow or shrink property to adjust the content for different situations and deal with too much/less space.
          Flexbox is mainly for a flexible structure where it can adjust different situations (for example if i have a sidebar with a fixed width set by ‘flex-basis: 250px’ which i can toggle on or of and the content uses ‘flex: 1’ to fit in the remaining space. By using the flex-basis property mainly to bring it back to the old ‘way of thinking’ we miss a lot what flexbox is really about.

          3
    • 13

      Or maybe with this approach…..

      .flexbox {
      display: flex;

      .content {
      flex: 3 3 40px;
      margin-right: 20px;
      }
      .sidebar {
      flex: 1 1 0;
      }
      }

      1
  5. 14

    Awesome question, Matt.

    You’re right here. We’re comparing apples to oranges when we compare Flexbox vs Susy. A better comparison would be between Flexbox and Float, or Susy with other frameworks.

    Although that’s the case, I received a great number of questions asking: “Should I use Flexbox or Susy?”.

    The underlying question here is that there are people who don’t understand the difference between a layout spec (like Flexbox) and a framework (like Susy).

    Hence, the challenge here is to explain the difference between the spec and the frameworks in a practical way that people can relate to (like creating grids).

    That was the aim I had when writing this article.

    8
  6. 15

    Agree with the commenters that this is something of a strange comparison. A better one would be with CSS Grid Layout and Susy (I’ve played around a bit with that in the past ).

    A lot of the problems people are raising with Flexbox is due to trying to make it behave like a two-dimensional grid system, and it hasn’t been designed for that. It would definitely be nice for flexbox to get proper gutters though, and it looks like that might one day happen.

    I’m concerned that the growing desire to see flexbox as the solution to all layout issues is just going to lead us down another path of hacky layout solutions. So a good way to look at “which to use” given that we don’t have Grid out in browsers yet is to consider whether you are developing something that is essentially one dimensional. If not then flexbox is probably just going to give you a different set of problems. Susy is a pretty good stopgap solution at this point, as at least it gets away from the defining layout in markup that is a feature of many grid frameworks.

    With excellent timing my 24 ways article today covers Grid and Flexbox and gives some context as to why you would choose to use one or the other.

    7
    • 16

      CSS Grid Layout vs Susy would be a strange comparison as well. We’re back at comparing specs vs tools again. The better comparison would be: Floats / Tables / Flexbox / Grid.

      Strictly speaking, Susy is in a world of it’s own. It cannot be compared to anything out there on the internet so far. Yet, people are always comparing, wondering if Susy, some other framework, or spec is the holy grail they need for all their layout work.

      We know that’s not true, and I understand your concern from the growing desire to see flexbox as the one solution. Grid may be a better solution for layout, but the lack of browser support isn’t going to make that happen anytime soon.

      Until browser support kicks in, we have to make do. It’s going to be a reality that people ARE going to start using hacky solutions. We can’t avoid that. We won’t know if anything is hacky until we’ve tried, and found out it doesn’t work as we wanted.

      The only thing we can do is to educate people regarding the strengths and weaknesses of each tool / system / framework / spec we use so we learn to work with them all, and use them properly depending on the circumstances. We cannot control what they end up using. We can just pray they don’t do hacky stuff.

      5
    • 17

      rachel,
      zell states at the beginning of the article he’s not making a direct comparison and that this perspective on his article would miss the point. stop making his opportunity to share with the community your cue to nit-pick linguistic semantics–it’s uncharitable at a time of the season well-known for giving thanks and sharing kindness. enough with the self-promotion in your closing which is in poor taste. and no one uses the word ‘latterly’ (from the “grid, flexbox….” article) btw. at least as much as they don’t want to appear to be speaking to others from a perspective that peers down their nose from above.

      0
  7. 18

    Great way to sharing this.I am really appreciate your point of view.Thanks for sharing.

    0
  8. 19

    It should probably be noted that Flexbox is a native solution you “just use” (on modern browsers), whereas Susy requires you to pollute your machine with NodeJS, NPM, Grunt and other hellishly unreliable build tools. This barrier alone is enough for me – not having to set up that mess of error-prone tools for a new project and just being able to dive in is priceless.

    -1
    • 20

      Actually the only Susy requirement is Sass – you can simply download the Susy folder from https://github.com/oddbird/susy/tree/master/sass , drop it in your project and import it in your main scss file. Happy days.

      1
      • 21

        indeed, but it must be pointed out that Sass on its own depends on other stuff. So effectively @Bruno had a point on that.

        I’m in favour of Susy mostly due to compatibility reasons. The gains of using flexbox can only be outweighed by that.

        0
  9. 22

    Hi, thanks for interesting article.
    I can suggest you to try Lost grid https://github.com/corysimmons/lost for basic grid usage, since it’s support flexbox also. But anyway not all of it’s features. So understanding flexbox model is highly recommended.

    1
  10. 23

    i am not sure how to achieve a 2 column layout with equal heights? For example a sidebar which adapts in height to fit the content section. In flex-box this is easily accomplished…

    1
    • 24

      If you need to work with heights… the best way I know right now is through Flexbox. All other methods requires you to use hacky methods :(

      0
  11. 25

    I liked this article. For me I learned more about susy and flexbox. I’m not to picky about whether it’s a valid comparison. I’m a fan of Zell’s writing and teaching style. I’ve learned a lot from him. Thanks Zell. Stay awesome!

    7
  12. 26

    Nice article! I think flexbox is the way to go. But one problem are older browsers – so not everybody is able to switch from float/inline-block to flexbox. That’s why I’ve written a new flexbox grid called gridilydidily with inline-block fallback. And yes – everything of this article is possible with gridilydidily ;)

    10
  13. 30

    The conceit of the article itself is flawed. You shouldn’t have to build ‘grid’-based systems using flexbox. Grid systems are, arguably, what is wrong with layouts in the modern web, and are one of the reasons the W3C built flexbox.
    Stop trying to use a hammer to drive in a screw, you aren’t using flexbox properly.

    1
  14. 31

    Hey Zell, great post and interesting as I have come up with a pen which demonstrates using both Flexbox AND calc, it would be inteesting to see what your thoughts are on it: http://codepen.io/morganfeeney/pen/MKYjwb

    What I have accounted for is columns of different widths and the desired gutter.

    0
  15. 32

    Great article,

    Shows how powerfull both are. I like the idea of combining the two. Or maybe use Jeet instead of Susy.
    You are comparing two different things – but I really don’t see the issue : ) They have equal results. Like nails and screws.

    Float and it’s evil cousin the tabel is the mother of layouts and flex is cooked up by this idea – correct me if I am wrong? All part of the evolution of web design.

    Grid systems are part of the evolution – and not evil. The specification of flexbox has changed. And Is implemented different in different browsers. So it is not fully stable yet : )

    1
    • 33

      Yeah everything is part of the evolution. We mix things up, try to force things in one way or another and see if they work, then learn from it.

      0
  16. 34

    Thanks for the great article, and for playing Devils Advocate. For me I still think we’re not there yet. Even with Suzy I’m compromised as if I use margin for gutters I can’t mix units. Yet if I use padding / box-sizing: border-box I can, yet the markup has to increase. I managed to find a middle ground using flex box and calc. It would be cool to see what you think of it: http://codepen.io/morganfeeney/pen/MKYjwb

    0
    • 35

      This looks cool. I’m personally not a fan of writing grid classes on the HTML, so I’d hold my comments. Here’s why I don’t like writing grid classes on the HTML if you’re curious.

      1
      • 36

        I did read that article after seeing this one. I read Rachel Andrew’s: here too. It’s interesting debate, there are 2 camps, ”separation of concerns” and the other one. I’m open to both. What I found immediately useful from Rachel’s article was the comparison to table layouts from 1999!

        In design we’re using a grid not a table, however you do pick these things up along the way without thinking.

        I’d like to see some examples of some eCommerce sites or some web layouts with lots of components, that have successfully implemented the good old ‘separation of concerns’ way of thinking, can you provide any?

        1
  17. 37

    Thanks for the article, I am convinced that I should stick with divs and floats for the time being as flex box is not properly implemented accross browsers and looks seriously flawed, plus the hacky examples to make it do what you want seem like a step backwards. At least divs and floats give me the control I need and I can do most things with careful planning. As for Susy, I don’t use css pre-processes,

    0
  18. 38

    Love it. Thanks for sharing, Zell.
    Anyway, I think on this pen http://codepen.io/zellwk/pen/qObPLX we should edit the margin-bottom of .gallery__item to be 2 * gutter. Because we use gutter-position: split. CMIIW.

    1
  19. 39

    Thanks Zell.
    I highly appreciate your articles and prefer Susy. Of course, flex box is worth to be taken in account but it has not been supported properly by IE.
    Very interesting article, huge amount of work behind it…

    1
  20. 40

    Hi. One question:

    You wrote: “Because Susy defaults to a float-based layout, we need to force the parent element (.susy) to clear its child elements to prevent the parent element from collapsing:

    .susy {
    @include clearfix;

    .content { @include span(9); }
    .sidebar { @include span(3 last); }
    }

    Isn’t the clearfix automatically generated, if you use the “@include container;” Tag? So we can use this too?

    0

↑ Back to top