Site icon Treehouse Blog

Flexbox: The Next Generation of CSS Layout Has Arrived

Rubber-Band-Duncan-Hull

Stretch your CSS layout options with Flexbox. Flickr photo by Duncan Hull.

(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 float and 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 position or float properties. It also doesn’t use any block or inline values for display.

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

The declaration 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.

This diagram from the W3C specification for flexbox describes how the main axis and cross axis relate 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 .header and .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.

flex-direction

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 flex-direction is row, so even if the flex-direction property wasn’t used at all, then the list elements would still appear horizontal.

flex

The flex property is applied to flex items. It’s a shorthand property that combines the flex-grow, flex-shrink, and flex-basis properties into one declaration. The flex-grow and 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, flex-grow is 0 and flex-shrink is 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 auto.

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 flex-grow is 0 by default, the .nav will always take up more space than the .logo.

justify-content

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 image from the W3C demonstrates how the various values for the justify-content property will behave.

And more…

This is just a small sample of the new flexbox properties. For more comprehensive information, see the resources section below.

Browser Support

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.

Flexbox Resources

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:

Join Nick on his course How to Make a Website

Exit mobile version