Using the CSS3 flexbox layout

The flexbox layout is a new CSS3 module for page layout. It can lay out items in a direction (left-to-right or top-to-bottom) with the items stretching to take up the available space. Quite complicated layouts can be built up by nesting flex containers.

Flexbox makes it simple to create stretchy layouts that can be dropped into a space and be easily resized when the layout is displayed on a smaller screen. It is designed to make common layout patterns like the three column layout very simple to implement.

Take a look at some examples of the kind of things flexbox is good at.

Flex containers and flex items

A flexbox layout is made up of a flex container and flex items inside the container.

A flex container is a HTML element with its display property set to flex. Any item inside a flex container is automatically a flex item.

Here’s an example of a three column layout. The outer container div is the flex container and the left, main and right divs are flex items:
the container div is a flex container and the left, main and right divs are flex items

The code for setting up a really simple flex container with no items would look like this:

  1. <div class="container"></div>
  1. .container {
  2.   display: flex;
  3. }

Flex-flow

Flex containers have a flex-flow CSS property which determines how the flex items will be laid out. A flex container with flex-flow set to row will be laid out from left to right:
flex-flow: row makes the contents go from left to right

One with flex-flow set to column will be laid out from top to bottom:
flex-flow: column makes the contents go from top to bottom

Here’s how you’d set the flex container to lay out its flex items in a row:

  1. .container {
  2.   display: flex;
  3.   flex-flow: row;
  4. }

A flex container can either have all of its items on a single line or it can support multiple lines. This is determined by whether the flex-flow is told to wrap or not. If the container supports wrap, an item which does not fit on the current line will be wrapped to the next line:
multiple line wrapping

Here’s how we’d make the flex container wrap:

  1. .container {
  2.   display: flex;
  3.   flex-flow: row wrap;
  4. }

Flex items

The elements inside the flex containers are automatically turned into flex items. No extra CSS configuration is needed. The only thing you will need to do is set their dimensions.

If the flex container has its flex-flow set to row, the flex items will need to have their width set. Their height will automatically be set to the height of the flex container:

If the flex container has its flex-flow set to column, the flex items will need to have their height set. Their width will be automatically set to the width of the flex container:

Use the width or height property to give your flex item a size that is independent of the other flex items. For example if we give the content div a width of 600px, it will be 600px wide no matter if there is one, two or a hundred other flex items in the container.

Use the flex property if you want your flex items to be sized according to the space left in the flex container. For example we can tell the browser that the left and right columns should take up any remaining space in the flex container after the content element has been sized.

The value of the flex property is proportional. If the left navigation is set to one and right navigation is set to two, the remaining space should be divided up so the right column is twice as wide as the left:

Here’s some sample CSS to set widths on some flex items that use a mixture of independent and proportional widths:

  1. .main {
  2.   width: 600px;
  3. }
  4. .left {
  5.   flex: 1;
  6. }
  7. .right {
  8.   flex: 2;
  9. }

Complete example

Here’s a really simple flexbox example that creates a classic three column page layout. The content div is 60% wide and the navigation divs use the flex property to be sized according the space left in the container:

  1. <div class="container">
  2.   <nav class="nav left">…</nav>
  3.  
  4.   <section class="main">
  5.     …
  6.   </section>
  7.  
  8.   <nav class="nav right">…</nav>
  9. </div>
  1. .container {
  2.   display: flex;
  3.   flex-flow: row;
  4. }
  5. .main {
  6.   width: 60%;
  7. }
  8. .left {
  9.   flex: 1;
  10. }
  11. .right {
  12.   flex: 2;
  13. }

See the complete example.

Browser support

At time of writing, in 2012, browser support for the finalized (or maybe just latest) syntax is not very good. These examples work in Opera and webkit (because I included the prefixes).

I haven’t included browser specific prefixes in my in-article examples to make them easier to understand. For the widest browser support in March 2013, you’ll need prefixes targetting for webkit and IE. You might also want to consider adding support for earlier version of the syntaxes. I personally think it’s better to hold off using flexbox until the final syntax gets wide enough support.

Posted on 23 Mar 13 by Helen Emerson (last updated on 29 Mar 13).
Filed under CSS