I don't really think of myself as a front-end developer, but I love CSS and I'm always practicing my FED skills. Flexbox has been one of the best additions to CSS in the last few years and with it comes some really simple grid systems.

It's actually possible to create a grid using flexbox with 2 lines of CSS. With a few extra lines, you can make the grid responsive and give the cells flexible margins.

A very basic grid

Here's the simplest flexbox grid:

.grid { display: flex; }
.column { flex: 1; }
<div class="grid">
  <div class="column">
    Column 1
  </div>

  <div class="column">
    Column 2
  </div>

  <div class="column">
    Column 3
  </div>

  <div class="column">
    Column 3
  </div>
</div>

Of course, you can use whatever classes you like for the container and columns. It looks like this:

Column 1
Column 2
Column 3
Column 4

Setting a minimum width

If you resize this page, you'll see that the columns "flex" to fill the space available. However, the columns can get very small and cramped. Let's give them a minimum width so they can't get too small.

.grid { display: flex; }
.column {
  flex: 1;
  min-width: 200px; }

If you're using Sass or CSS variables, it's a good idea to make the min-width a fraction of your full page width so you don't have to worry about selecting a number yourself.

We're still only at 4 lines of CSS.

Column 1
Column 2
Column 3
Column 4

However, now our columns don't shrink past their minimum width, and end up overflowing their container if the viewport is to small. Resize the window and you'll see these columns squeeze off the right side of the page.

Wrapping

The solution to this is flex-wrap. This property on the parent container will tell it to wrap the items if there isn't enough space for them in a row. Let's add that to the container:

.grid {
  display: flex;
  flex-wrap: wrap; }

.column {
  flex: 1;
  min-width: 200px; }

This gives us a responsive-ish grid:

Column 1
Column 2
Column 3
Column 4

We can add borders to the columns to better see what's happening:

Column 1
Column 2
Column 3
Column 4

Adding column margins

We might want to put a little space between our columns. If we're using multiple columns for text, we don't want the columns to bump up against one another.

.grid {
  display: flex;
  flex-wrap: wrap; }

.column {
  flex: 1;
  min-width: 200px;
  margin: 20px; }

This gives our columns some breathing room:

Column 1
Column 2
Column 3
Column 4

This works well, but our content isn't aligned with the content outside the container, and between rows and columns we get twice as much space, since our columns have margins on all sides.

An almost solution

It might seem that an easy solution to this is to only put margins on, say, the right and bottom sides of our columns.

.grid {
  display: flex;
  flex-wrap: wrap; }

.column {
  flex: 1;
  min-width: 200px;
  margin-right: 10px;
  margin-bottom: 10px; }

This isn't ideal. We still have a right margin on our rightmost column.

Column 1
Column 2
Column 3
Column 4

You can fix this in a single row of columns by selectively removing margins for the last column using the :last-child selector, but this "solution" goes out the window as soon as your columns wrap — the last child gets wrapped to another line of columns and the column at the end of the row it used to be in now has an extra margin, since it's not the last child of the container.

A decent solution: negative margins

We can get around this creatively by using negative margins on the container element and margins on all sides of our columns. Bear with me here:

.grid {
  display: flex;
  flex-wrap: wrap;
  margin: -10px; }

.column {
  flex: 1;
  min-width: 200px;
  margin: 10px; }
Column 1
Column 2
Column 3
Column 4

Now we have columns that are flush with the edges of their containing element, with equal spaces between one another that stay equal when the columns change shape or are wrapped to different lines.

One of the most amazing things about this grid, to me, is that it's responsive without using a single media query. Flexbox makes the grid items responsive, and a minimum width ensures that they don't become unusable.

Drawbacks

This isn't perfect. Your container element actually extends outside its parent, so if it has a background, for example, it'll seem misaligned. However, for very specific use cases where you need a simple grid, I think this is the way to go.

And it's only 8 lines of CSS!

Adam Hollett's face against a dark wood background

Adam Hollett is a developer and technical writer at Shopify in Ottawa, Ontario.