(Stretch your CSS layout options with Flexbox. Flickr photo by Duncan Hull.)
Flexbox is a totally new set of CSS properties that allows designers to create flexible layouts. This is great news for responsive design because it dramatically reduces the complexity of fluid grids. Browser support for flexbox is finally here, so if you haven’t learned about flexbox yet, then it’s time to get started.
Flexbox is Ready
The web was originally conceived as a mechanism for exchanging scientific documents. Web technology has evolved a great deal since then, but we still rely on CSS properties that have their roots in digital publishing. Indeed, CSS layout and positioning are some of the most difficult concepts for web designers, regardless of experience. Designers rely on the use of CSS properties like
clear, or CSS declarations like
display: block; and
display: inline; to control their designs. With
display: flexbox; designers are now in control of the direction, alignment, and spacing of page elements.
Free trial on Treehouse: Do you want to improve your web design skills? Click here to try a free trial on Treehouse.
Flexbox is a remarkably intelligent solution to a long-standing convoluted problem. For the last few years, designers have been patiently waiting for browser support to catch up to the CSS Flexible Box Layout Module specification. Finally, the latest versions of all major browsers include flexbox support. (For more detailed information, see the browser support section below.)
Flexbox Example and Syntax
Flexbox and media queries make for a powerful combination. In the following example, I’ve recreated a simplified version of the Treehouse homepage header using a mobile-first flexbox approach. Open this pen in a new browser window and resize the window to see the header in action.
See the Pen Treehouse Flexbox Example by Nick Pettit (@nickpettit) on CodePen.
At first glance, it may not appear very special. However, if you look at the code, you’ll notice that this layout uses no
float properties. It also doesn’t use any
inline values for
I’ve separated the example CSS into the flexbox styles and then all the less relevant code that just makes it look nice. Here’s how each part of the flexbox styling is working in this example.
display: flex; defines a “flex container” and its direct children automatically become “flex items.” A flex container has a main axis, which is the primary direction in which flex items are laid out. The cross axis is perpendicular to the main axis. Both the main axis and the cross axis have a set of properties that can control how flex items are placed in relation to one another.
You can also nest flex containers inside one another, which I’ve done in the example code, since the display property is not automatically inherited. Both the
.nav classes have the
display: flex; declaration applied. This is similar to how rows and columns in a CSS framework like Foundation can be nested.
One thing to note is that the main axis is the primary direction, and not necessarily the horizontal direction. The direction of a flex container can be changed with the
flex-direction property. At mobile sizes, the navigation in the example becomes a 1-column list rather than horizontal links. This is accomplished in the example with the
flex-direction: column; declaration.
Then, at larger sizes, the declaration
flex-direction: row; is used to make the navigation horizontal again. The default value for
row, so even if the
flex-direction property wasn’t used at all, then the list elements would still appear horizontal.
flex property is applied to flex items. It’s a shorthand property that combines the
flex-basis properties into one declaration. The
flex-shrink properties both take a unitless value that defines how much space each element should take up in proportion to one another. By default,
1, meaning that all the elements will be in proportion to one another. The
flex-basis property defines the size of elements before extra space is distributed and its default value is
The latter two properties are optional, so if we simply apply the declaration
flex: 1; to the
.nav class, it changes the
flex-grow value to
1. The other flex item in the same flex container is the
h1 element with the class
.logo, and since
0 by default, the
.nav will always take up more space than the
If there’s space left over inside a flex container, either because the flex items have reached their maximum size or because they’re inflexible, then the
justify-content property can define how the space should be used. In the example, the
.header has the declaration
justify-content: space-between; which means the first flex item will be at the start of the line, the last item will touch the end of the line, and anything between will be evenly distributed. On the nested
.nav flex container, the declaration
justify-content: space-around; is used to distribute the remaining space evenly around each navigation link.
See this diagram from the W3C to see how each of the justify-content properties behave.
This is just a small sample of the new flexbox properties. For more comprehensive information, see the resources section below.
In general, if you only need to support the latest browsers (such as a blog for web designers) then you’re safe to use flexbox. However, there are a few caveats that need to be addressed for slightly older browsers. For example, as of Safari 7.0 and mobile Safari 7.0, the
-webkit- prefix is still required.
More importantly, there are multiple implementations of the flexbox syntax. Prior to the introduction of the modern syntax in the W3C spec, an unofficial syntax was supported by several legacy browsers. In addition, there’s an even older
display: box syntax. There are also a few bugs to watch out for (even in modern browsers) that may or may not be minor, depending on the context of a project.
For specific information about browser support, see the Can I Use support table for flexbox. You may also want to read about how to support flexbox in legacy browsers.
One more note: It’s probably not a good idea to use flexbox for overall page layouts. Rendering content with flexbox causes horizontal misalignment and shifting as the page is loading, due to the way sizes need to be calculated. This can actually make the page load a bit slower in most instances. However, the grid layout module aims to further address page layout and browser support should arrive in the future.
This article is only meant to spread awareness and excitement about the arrival of flexbox, and there’s a lot more to learn. If you’re thinking about using flexbox, here’s some essential reading:
- CSS Layout Techniques: In this Treehouse course, Guil Hernandez covers common layout and positioning methods, including flexbox.
- A Complete Guide to Flexbox | CSS-Tricks: If you want to know more about each element and property in the flexbox module, I recommend this guide from Chris Coyier.
- Flexbox in the real world: A fantastic blog post from Sean Fioritto about how to use flexbox responsibly to accommodate various browser traffic scenarios, including detailed code to help support legacy browsers if necessary.
- The Ultimate Flexbox Cheat Sheet: An excellent “cheat sheet” page (also from Sean Fioritto) about how to use various flexbox properties and values.
- CSS Flexible Box Layout Module | W3C: For extremely detailed technical information, read the W3C flexbox specification.
- Flexplorer: Amazing tool by Bennett Feely that allows you to quickly experiment with the various flexbox properties and values.
Join Nick on his course How to Make a Website