An Introduction to Flexbox

Meet Flexbox. The CSS3 Flexible Box, or more widely known as Flexbox, is a new and powerful layout mode in CSS3. It provides us with a box model optimized for laying out user interfaces. With Flexbox, vertical centering, same-height columns, reordering and changing direction is a breeze. This is  thanks to its layout algorithm being direction-agnostic (as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased).

Flexbox is pretty easy and straightforward to use. However, implementing it on more complex layouts can get a little out of hand so it should only be used for small application components and simpler layouts.

Browser support for Flexbox is pretty good. According to caniuse.com around 93% of people are now running a browser that supports it.

Basics

flex-terms

In the picture above you can see the properties and the terminology that’s used to describe the flex container and flex items.

  • main axis – The main axis of a flex container is the primary axis along which flex items are laid out. It’s not necessarily horizontal (depending on the flex-direction property).
  • main-start | main-end – The flex items are placed within the container starting from main-start and going to main-end.
  • main size – A flex item’s width or height, whichever is in the main dimension, is the item’s main size. The flex item’s main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
  • cross axis – The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
  • cross-start | cross-end – Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
  • cross size – The width or height of a flex item, whichever is in the cross dimension, is the item’s cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.

How to use Flexbox

The HTML is as simple as it gets:

To use Flexbox we need to set the display property to flex on parent element (.flex-container).

All immediate child elements (.flex-item) are automatically set to flex items.

Prefixing

To support the most browsers possible, Flexbox requires us to add some vendor prefixing. The problem is that the flexbox spec has changed over time, creating an “old”, “tweener”, and “new” versions. Prepending properties with the vendor prefix (-moz-, -webkit-, -ms-) isn’t enough cause there are actually entirely different property and value names in different flexbox spec versions.

The best way to handle this is to run CSS through Autoprefixer which passes CSS and adds vendor prefixes to CSS rules using values from caniuse.com.

Note: all CSS in the following code snippets is un-prefixed.

Flexbox container properties

Notes about flex container:
* all of the column-* properties have no effect on a flex container.
** the ::first-line and ::first-letter pseudo-elements do not apply to flex containers.

flex-direction

This property is used to specify the direction of the flex container’s main axis, thus defining the direction flex items are placed in the flex container.

Values:

flex-container-1
With row direction the flex items are stacked in a row from left-to-right in ltr context.

flex-container-2
With row-reverse direction the flex items are stacked in a row from right-to-left in ltr context.

 With column direction the flex items are stacked in a column from top-to-bottom
With column direction the flex items are stacked in a column from top to bottom.

With column-reverse direction the flex items are stacked in a column from bottom-to-top.
With column-reverse direction the flex items are stacked in a column from bottom-to-top.

* default value for flex-direction is row
** row and row-reverse are dependent of the writing mode so in rtl context they will be reversed.

flex-wrap

By default the flex container fits all flex items into one line. Using this property we can change that. We can tell the container to lay out its items in single or multiple lines, and the direction the new lines are stacked in.

Values:

Flex items are displayed in one row, by default they are shrunk to fit the flex container’s width
Flex items are displayed in one row and by default they are shrunk to fit the flex container’s width.

Flex items are displayed in multiple rows if needed from left-to-right and top-to-bottom.
Flex items are displayed in multiple rows if needed from left-to-right and top-to-bottom.

Flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top.
Flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top.

* default value for flex-wrap is nowrap
** these properties are dependent of the writing mode so in rtl context they’ll be reversed.

flex-flow

flex-flow property is a shorthand flex-direction and flex-wrap properties.

Values:

* default value for flex-flow is row nowrap

justify-content

justify-content property aligns flex items along the main axis of the current line of the flex container. It helps distribute left free space when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size.

Values:

Flex items are aligned to the left side of the flex container in ltr context
Flex items are aligned to the left side of the flex container in ltr context.

Flex items are aligned to the right side of the flex container in ltr context.
Flex items are aligned to the right side of the flex container in ltr context.

Flex items are aligned at the center of the flex container.
Flex items are aligned at the center of the flex container.

Flex items are displayed with equal spacing between them, first and last flex items are aligned to the edges of the flex container.
Flex items are displayed with equal spacing between them. The first and last flex items are aligned to the edges of the flex container.

Flex items are displayed with equal spacing around every flex item, even the first and last flex items.
Flex items are displayed with equal spacing around every flex item, even the first and last flex items. Note that the first items left margin and the last items right margin are not equal to the others.

* default value for justify-content is flex-start

align-items

The align-items property defines how flex items are laid out along the cross axis on the current line. You can think of it as the justify-content version for the cross-axis.

Values:

Flex items fill the whole height (or width) of the flex container.
Flex items fill the whole height (or width) of the flex container.

Flex items are stacked to the cross start of the flex container,
Flex items are stacked to the cross start of the flex container.

Flex items are stacked to the cross end of the flex container.
Flex items are stacked to the cross end of the flex container.

Flex items are stacked to the center of the cross axis of the flex container.
Flex items are stacked to the center of the cross axis of the flex container.

 Flex items are aligned in a way that their baselines are aligned.
Flex items are aligned in a way that their baselines are aligned.

* default value for align-items is stretch

align-content

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis (similar to how justify-content aligns individual items within the main-axis).

Values:

Flex items are displayed with distributed space after every row of flex items.
Flex items are displayed with distributed space after every row of flex items.

Flex items are stacked toward the cross start of the flex container.
Flex items are stacked toward the cross start of the flex container.

Flex items are stacked toward the cross end of the flex container.
Flex items are stacked toward the cross end of the flex container.

Rows of flex items are stacked in the center of the cross axis of the flex container.
Rows of flex items are stacked in the center of the cross axis of the flex container.

Rows of flex items are displayed with equal spacing between them, first and last rows are aligned to the edges of the flex container.
Rows of flex items are displayed with equal spacing between them. The first and last rows are aligned to the edges of the flex container.

Flex items are displayed with equal spacing around every row of flex items.
Flex items are displayed with equal spacing around every row of flex items. Note that first rows top margin and last rows bottom margin are not same as the others.

* default value for align-content is stretch

Flexbox item properties

Notes about flex items:
* float, clear and vertical-align have no effect on a flex item, and do not take it out-of-flow.

order

By default, flex items are laid out in the order they are added inside the container. Using the order property we can control the order in which they appear in the flex container.

Values:

Flex items can be reordered with this simple property, without changing the HTML.
Flex items can be reordered with this simple property, without changing the HTML.

* default value for order is 0

flex-grow

This property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items.

Values:

If all flex items have same value for flex-grow than all items have same size in the container.
If all flex items have same value for flex-grow than all items have same size in the container.
The third flex item takes up more space relative to the size of the other flex items.
The third flex item takes up more space relative to the size of the other flex items.

* default value for flex-grow is 0
** negative numbers are invalid

flex-shrink

The flex-shrink specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items.

Values:

By default all flex items can be shrunk, but if we set it to 0 they will maintain the original size.
By default all flex items can be shrunk, but if we set it to 0 they will maintain the original size.

* default value for flex-shrink is 1

flex-basis

This property takes the same values as the width and height properties, and specifies the initial main size of the flex item.

Values:

lex-basis is specified for the third flex item and dictates the initial size of the element.
Flex-basis is specified for the third flex item and dictates the initial size of the element.

* default value for flex-basis is auto

flex

This property is the shorthand for the flex-grow, flex-shrink and flex-basis properties. Among other values it also can be set to auto (1 1 auto) and none (0 0 auto).

* default value for flex is 0 1 auto
** W3C encourages to use the flex shorthand rather than the separate component properties, as the shorthand correctly resets any unspecified components to accommodate common uses.

align-self

This align-self property allows the default alignment (or the one specified by align-items) to be overridden for individual flex items. Refer to align-items explanation for flex container to understand the available values.

Values:

All flex items have overridden alignment through the align-self property.
Flex items 1,3,4 have overridden alignment through the align-self property.

Conclusion

There you go! All Flexbox properties in one place!

I encourage you to go and try to build a few simple page layouts with it. You’ll be pleasantly surprised at the flexibility (no pun intended) it provides.

If you don’t feel like making something from scratch, you can experiment with all Flexbox properties using this great tool built by Dimitar Stojanov.

Resources and inspiration:

About Luka Čavka

I’m a front-end developer from Split, Croatia, with a passion for responsive web development, especially HTML and CSS coding. During 7+ years of professional experience I have worked with clients from various fields and have published more than a few hundred websites. In my spare time I enjoy tinkering with new front end tools/techniques and having a beer (or two) at the local pub.