Creative Geek: IMHO

Web design & development, data visualization, UI/UX, pretty things, zombies and whatever else by Chienyi Cheri Hung

Creative Geek: IMHO


Column Layout Using CSS Flexbox

Flexbox is currently a W3C recommendation and only supported by (some) modern browser. But its approach is so much more native to how the web should behave. The concept also aligns well with the dominant responsive design. Flexbox seems destined to be the new standard one day.

Know all you need to know about flexbox from this CSS-TRICKS post and this ultimate cheatsheet.

Let's check out a column layout using flexbox.

A column-based layout typically involves assigning a float to the each column/block. Set a width to the column while also taking into account any margin or padding values. (width of all columns) + (all gutter size) = 100% of the page width.

This math isn't so hard. But when you want to change the number of columns in a row, you have to redo the calculation all over again.

Ok, so the chance of changing column count on a set layout frequently is low. Still, the idea of having to set an element to "float" in order to have them be stacked horizontally has always seem hacky to me. It's assuming that the web page can only be vertical. Any other direction requires making the elements unattached and "floating."

What is more natural semantically and conceptually is flexbox's flow-direction.

In the codepen example, the divs appear to be lined up side by side simply by setting a flex-direction value.

See the Pen Layout and Decorative Header using Flexbox by Chienyi Cheri Hung (@cherihung) on CodePen.

.content {
  display: flex; //makes .content a flex container
  flex-direction: row; //line the elements side by side in a row
  flex-wrap: nowrap; //fit all elements in the row

*flex-direction defaults to row and flex-wrap defaults to nowrap. The code is there for illustrative purpose.

Wait, so a column-like layout actually should be defined with flow-direction: row? Well, yes. Because column layout is really describing putting items in a horizontal (i.e. row) direction.

flow-direction: row evenly arranges the elements horizontally, one next to another.

flow-direction: column evenly arranges the elements vertically, one on top of another.

With flex-wrap setting or defaulting to nowrap, the browser will position all the elements in one line.

If a fixed width for the .content container was defined, all the elements will size itself to fit in it. To have them space out evenly no matter the change in container or browser size, set each to a width: 100%.

The browser will keep each block 100% proportionally to the page width and include the padding/margin size in its calculation automatically. This way you can define a gutter size once and not worry about it anymore.

.content .item {
  padding: 0 1em; //create a gutter
  width: 100%; //to evenly size column

Images require an additional max-width definition. This makes sure no matter how large an image is, it will not exceed its container and auto-size proportionally.

.content img {
  max-width: 100%;

Now, when you add another <div class="item">, it will increase the number of columns accordingly.

Nothing is without its pain point. Flexbox is no exception.

A flex container will always auto-calculates the size and spacing of its direct children. This can cause unintended shifting in spacing and positions. It also introduces a bit more complexity wwhen it comes to overflow scroll elements in a full-height web page. For some good examples on how to use flexbox in various layout situations, checkout Solved by Flexbox.