I've been using flexbox for over a year for layout in CSS. Unlike its sibling CSS Grid, flexbox has had widespread browser support for a long time. This is a short summary of what flexbox does, and some uses for it in practice.
What is Flexbox?
Flexbox is a layout system which allows you to abstract away a lot of the specifics of laying out items in a grid. It caters to use-cases which have historically been clunky to implement, including creating complex rows and columns, laying out flexible elements, adapting to bidirectionality, and overriding source ordering.
The best at-a-glance resource I've found for flexbox is the brilliant visual CSS-Tricks guide. Rather than repeat the comprehensive documentation already available elsewhere, here's a brief summary.
Flexbox layouts are composed of two types of elements—a parent flex container, and a number of children. Creating a flex container is as simple as setting display: flex; (or display: inline-flex;) on it. When you set display: flex; on a flex container element, these are the default properties it receives:
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
flex-directionsets the overall flow of the elements in the containerflex-wrapcontrols whether elements will wrap if they exceed the size of the containerjustify-contenttells the container how to distribute the child elements when there is spare space along theflex-directionaxisalign-contentsets the aligment of child elements on theflex-directionaxisalign-itemssets the alignment of child elements perpendicular to theflex-directionaxis
You can also set flex-direction and flex-wrap using the shorthand:
flex-flow: <'flex-direction'> || <'flex-wrap'>;
The child elements will have these default properties:
order: 0;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: flex-start;
orderdetermines which elements have predecence along theflex-directionaxis (similar toz-index)flex-growdetermines whether an element can expand to fill free spaceflex-shrinkdetermines whether an element can shrink to make space for other childrenflex-basissets the base size of an element before it grows/shrinksalign-selfallows the child element to override the value set in the parentalign-itemsfor a specific element
You can also set flex-grow, flex-shrink, and flex-basis using the shorthand:
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
The great thing about both the parent and child properties is that they are all relative to the flex-direction set on the parent element. This makes it incredibly easy to influence the layout without needing to change other styling. flex-direction is also determined based on the dir attribute, making it even more adaptive.
Use cases
Holy grail
The classic three-column 'holy grail' layout with a sticky footer. This uses flex-direction: column; on the wrapper to create the base layout with flex-grow: 1; set on the content area to expand it to fill the page window, and a standard column layout in the content area with column precedence set using order.
Bidirectional
A simple bidirectional grid layout which reflows based on the directionality of the <body> element. Since other properties are already set relative to the flex-direction, this is incredibly powerful when used for more complex layouts.
Trello
A basic Trello-like layout of cards in columns. This uses a column layout inside a grid of tall rows to create a card structure. See the Bugs section below for a limitation of this pattern.
Flexible grid
A simple flexible grid of small and large items, constructed using flex-basis and flex-grow to control the relative sizing of elements. This also features a work-around to prevent rows or orphaned elements expanding to take up the whole row, by placing a zero-height element with a large flex-grow value at the end of the content.
Bugs
When creating the Trello example I found a bug in the browser implementation of flex-direction: column; which appears to be widespread (see the Chromium bug report and a related Stack Overflow post). The issue comes from the browser's calculation of the width of the flex container—after the first row, the container fails to expand to encapsulate the remaining rows (presumably because container width calculation is traditionally horizontally- rather than vertically-driven). This can be avoided if you can give your column a defined width, but the specific case of having an expanding column layout doesn't yet seem to be supported.
Flexbox resources
A few resources I've found helpful when learning and using flexbox:
- Flexbox Froggy, a simple game to help you remember what each property does
- A Complete Guide to Flexbox from CSS-tricks
- The CSS Flexible Box Layout reference from the Mozilla Developer Network