Flexbox Grid System

Many developers are familiar with CSS grid systems such as Bootstrap, which are historically built using floats and percentage widths. Browser usage has now progressed such that Flexbox is well supported, so using a grid system based on Flexbox offers some key advantages over floats, including:

  • simpler syntax
  • equal height columns
  • reordering sibling content

The v4 Bootstrap boasts a Flexbox grid, however this likely includes a lot of code bloat. I have recently tried my hand at writing a lightweight CSS grid with Flexbox which was surprisingly straightforward. This article will detail how this grid system works.

Rows

The general structure is the same as traditional grids, with the parent row and child column structure, so we start with defining a row as a flex container.

.row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -1rem;
  margin-right: -1rem;
}

The second property enables row wrapping, which means that a single .row container can effectively become a multi-row layout. More on this later. We use negative margins on the left and right to offset the column padding, as per traditional grid systems.

Columns

We define a base class for columns:

.col {
  flex-grow: 1;
  flex-basis: 100%;
  padding-left: 1rem;
  padding-right: 1rem;
}

We make the column fill the available space evenly with flex-grow: 1 and we make the column full width with flex-basis: 100%, effectively making it a single column layout by default.

<div class="row">
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
</div>

dark

Simple Grid

Some use cases for a grid layout have uniform column widths, e.g. a three column grid having all columns at 33.3333% width. Instead having a class name of each individual column, we can apply the styles from a single class name at the row level.

<div class=“row -three-col-xs">
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
</div>

We can create variants of these class names for different breakpoints:

-two-col-xs
-three-col-xs
-four-col-xs
All widths
-two-col-sm
-three-col-sm
-four-col-sm
SM breakpoint and up
-two-col-md
-three-col-md
-four-col-md
MD breakpoint and up
-two-col-lg
-three-col-lg
-four-col-lg
LG breakpoint and up
-two-col-xl
-three-col-xl
-four-col-xl
XL breakpoint and up

See the Pen Flexbox Grid System - example 2 by Tim Holt (@astrotim) on CodePen.dark

Complex Grid

Inevitably, you will need to control the widths of individual columns, which we do at the column level. Borrowing from the Bootstrap naming convention, we can use the following class names:

-xs-3 -sm-3 -md-3
-lg-3 -xl-3
3 of 12 columns
-xs-4 -sm-4 -md-4
-lg-4 -xl-4
4 of 12 columns
-xs-6 -sm-6 -md-6
-lg-6 -xl-6
6 of 12 columns
-xs-8 -sm-8 -md-8
-lg-8 -xl-8
8 of 12 columns
-xs-9 -sm-9 -md-9
-lg-9 -xl-9
9 of 12 columns
-xs-12 -sm-12 -md-12
-lg-12 -xl-12
12 of 12 columns

Visual position and source order

We can now leverage the order property of Flexbox to change the visual position of a column relative to its source order. This is particular useful for controlling the content order on mobile.

Consider a two column layout, with a main content area and a sidebar:

<div class=“row">
  <main class="col -md-9"></main>
  <aside class="col -md-3"></aside>
</div>

We can display the sidebar on the left on larger screens using the order property:

@media (min-width: 800px) {
  aside {
  order: -1;
  }
}

Alignment

We can position columns using the property justify-content. For example, to centre align a single column, we can create a -centred class:

.-centred {
  justify-content: center;
}

Leave a Comment