Using flexbox to lay out web applications

Using flexbox can help you design compelling layouts in web applications that scale better from desktop to mobile. Put an end to floating <div> elements, absolute positioning, and JavaScript hacks, and start building horizontal and vertical flowing layouts in just a few lines of CSS. Some basic example use cases:

  • You want to center an element inside the middle of a page
  • You want a set of containers that flow vertically, one after another
  • You want to create a row of buttons or other elements that collapses vertically on smaller screen sizes

This article only covers the use of flexbox with browsers that support the modern, unprefixed implementation of the standard. For information on vendor prefixes for older browsers please see the more general guide to using CSS flexible boxes.

Basics

You can make the elements inside any <div> flow with flexbox by setting the display property to flex and then setting the flex-flow property to either row, if you want the elements to flow horizontally, or column, if you want the elements to flow vertically. If you are using a horizontal flexbox and want your content to wrap vertically, then also specify the wrap value.

Then, for each element that you want to be part of the flex flow, set the flex property. Generally you will want to use one of the three following values:

  • If you want an element that only takes up its allocated width, like a button, use flex: none that expands to 0 0 auto.
  • If you want to explicitly size an element, use flex: 0 0 size. For example: flex 0 0 60px.
  • If you want an element that expands to fill space available, that is sharing space equally if there are multiple elements of this kind within the flow, use flex: auto. It expands to 1 1 auto.

There are other possibilities of course but this should cover the basic use cases. Let's see how this applies in a few examples.

Centering an element inside a page

For this case, the easiest thing to do is create two flexible boxes, one inside another. Each flexbox will have three elements: two of them pad the centered element, and then the centered element itself.

CSS Content

.vertical-box {
  display: flex;
  height: 400px;
  width: 400px;
  flex-flow: column;
}
.horizontal-box {
  display: flex;
  flex-flow: row;
}
.spacer {
  flex: auto;
  background-color: black;
}
.centered-element {
  flex: none;
  background-color: white;
}

HTML Content

<div class="vertical-box">
  <div class="spacer"></div>
  <div class="centered-element horizontal-box">
    <div class="spacer"></div>
    <div class="centered-element">Centered content</div>
     <div class="spacer"></div>
  </div>
  <div class="spacer"></div>
</div>

Result

Flowing a set of containers vertically

Imagine that you have a page laid out with a header section, a content section, and a footer. The header and footer should have a fixed size, but the content should resize according to available space. This can be done by setting the content's flex property to auto and  flex property on the header, and the footer, to none.

CSS Content

.vertical-box {
  display: flex;
  height: 400px;
  width: 400px;
  flex-flow: column;
}
.fixed-size {
  flex: none;
  height: 30px;
  background-color: black;
  text-align: center;
}
.flexible-size {
  flex: auto;
  background-color: white;
}

HTML Content

<div id="document" class="vertical-box">
  <div class="fixed-size"><button id="increase-size">Increase container size</button></div>
  <div id="flexible-content" class="flexible-size"></div>
  <div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
</div>

Javascript Content

var height = 400;
document.getElementById('increase-size').onclick=function() {
  height += 10;
  if (height > 500) height = 500; 
  document.getElementById('document').style.height = (height + "px");
}

document.getElementById('decrease-size').onclick=function() {
  height -= 10;
  if (height < 300) height = 300; 
  document.getElementById('document').style.height = (height + "px");
}

Result

This example has been set up so that click on the header will increase the size and clicking on the footer will decrease size. Watch how the content automatically resizes appropriately, while keeping the header and footer sizes constant.

Creating a collapsing horizontal container

In some cases you might want to lay a set of information out horizontally where the screen size permits, but collapse the contents horizontally where it does not. This is quite straightforward with flexbox. You can do this by adding the wrap value to the flex-flow property.

CSS Content

.horizontal-container {
  display: flex;
  width: 300px;
  flex-flow: row wrap;
}
.fixed-size {
  flex: none;
  width: 100px;
  background-color: black;
  color: white;
  text-align: center;
}

HTML Content

<div id="container" class="horizontal-container">
  <div class="fixed-size">Element 1</div>
  <div class="fixed-size">Element 2</div>
  <div class="fixed-size">Element 3</div>
</div><button id="increase-size">Increase container size</button><button id="decrease-size">Decrease container size</button>

Javascript Content

var width = 300;

document.getElementById('increase-size').onclick=function() {
  width += 100;
  if (width > 300) width = 300; 
  document.getElementById('container').style.width = (width + "px");
}

document.getElementById('decrease-size').onclick=function() {
  width -= 100;
  if (width < 100) width = 100; 
  document.getElementById('container').style.width = (width + "px");
}

Result

See also

Document Tags and Contributors

 Contributors to this page: fscholz, teoli, Dholbert, wlach, Sheppy
 Last updated by: fscholz,