Simple Flexbox Grid System

bender-grid
… with blackjack, and hookers! (ref)

Introduction and Requirements

A while ago, I created a small and simple flexbox-based grid system for use in the projects we make at work. The developed Grid System inspired upon how Bootstrap works:

  • it divides the grid into 12 columns (configurable).
  • it supports gutters in between columns (configurable).
  • it supports different viewport sizes, linked to keywords:
    XXS, XS, SM, MD, and LG (configurable).
  • it allows columns to adjust size based on the viewport size.
    Eg. .column-xs-12 applies only to the XS layout, .column-md-6 only applies to the MD layout, .column-lg-4
  • it allows offsetting of columns, also reliant upon the viewport size.
    Eg. .offset-md-4, .offset-lg-6.
  • it allows nesting of grids, keeping the defined gutter in place.

Along with that, a few extra requirements/features were added:

  • it must be standalone
  • it must use flexbox – not floats – for layout.
  • it must use em-based units – not px-based units – for sizing (where appropriate).
  • it must support viewport-unreliant column sizing. Eg. .column-8.
  • The columns must fill up the entire width of the wrapper/row. E.g. no (half-)gutter to the left of the first column, and no (half-)gutter to the right of the last column.
  • (added 2016.10.18) it must support auto and stretch columns in case you want to go off-grid

css-flexbox-grid

Demo

Embedded below is the source and the demo pen. The CSS is written in Stylus, our CSS preprocessor of choice.

See the Pen Flexbox Grid by Bramus! (@bramus) on CodePen.

TIP: You might want to check out the pen in a standalone tab/window, so that you can resize it.

How to use

To get started, add .has-columns onto the wrapper. For each column add .column along with one ore more size specifications such as .column-xs-4 and (optional) an offset specification such as .offset-xs-2.

Column size names are based on portions/units. A column .column-xs-4 for example is 4 units of the total of 12 columns, resulting in a column of approximately – depending on the gutter size – 33% in width.

<div class="has-columns">
    <div class="column column-xs-4">.column-xs-4</div>
    <div class="column column-xs-4">.column-xs-4</div>
    <div class="column column-xs-4">.column-xs-4</div>
</div>

See the pen embedded above for some examples.

Columns with the classname .column-auto will not take up a given portion, but will only take up the space their content requires. This kind of column is typically used in combination with a column .column-stretch. An example would be for a message-component that consists of an avatar and a content:

<div class="message">
    <div class="has-columns">
        <div class="column column-auto">
            <img class="message__avatar" src="avatar.png" alt="" title="" />
        </div>
        <div class="column column-stretch">
            <div class="message__text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
        </div>
    </div>
</div>

How it works

tl;dr: the width of each column is adjusted – using calc() – to take the defined gutter into account.

Say you have 2 columns that you want to display, each being 6 units wide (e.g .column-6). We can safely state that their base-width is 6/12, or 50% each.

<div class="has-columns">
    <div class="column column-6">.column-6</div>
    <div class="column column-6">.column-6</div>
</div>

In between those two columns a gutter of 1em is injected, using margin-right on the first column. There’s no gutter to the left of the first column, nor to the right of the second column (put differently: all columns, except for the last one, get a gutter applied using margin-right).

Given our 2 columns of 50% width each, this yields of a combined width that exceeds 100%: 50% (base-width) + 1em (gutter) + 50% (base-width) + 0em (no gutter for the last column!) = 100% + 1em = too wide.

css-grid-notadjusted
Columns without adjusted width = too wide

To not exceed 100%, the actual width of our columns need to be adjusted by (in this case) -0.5em each, neutralizing the 1em gutter in between. With the adjustment applied, this yields a combined width of exactly 100%: 50% (base width) – 0.5em (adjustment) + 1em (gutter) + 50% (base width) – 0.5em (adjustment) + 0em (no gutter for the last column!).

css-grid-adjusted
Columns with adjusted width= perfect fit

For 3 columns (each being 4 units wide, or 4/12, or 33.3333% base-width each) a total gutter worth of 2em is injected. The adjustement for these 3 columns therefore is 0.666666667em.

If one would derive a formula to calculate the $gutterAdjustmentPerColumn, it’s this:

$gutterAdjustmentPerColumn = $gutterSize * (1 - ($columnWidthInUnits / $totalNumberOfColumns))

The same logic – albeit a tad different – is used to calculate the $offsetAdjustmentPerColumn

Simple Flexbox Grid System →

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.