A Visual Guide to CSS3 Flexbox Properties

Related Course

Get Started with JavaScript for Web Development

JavaScript is the language on fire. Build an app for any platform you want including website, server, mobile, and desktop.

The Flexbox Layout officially called CSS Flexible Box Layout Module is new layout module in CSS3 made to improve the items align, directions and order in the container even when they are with dynamic or even unknown size. The prime characteristic of the flex container is the ability to modify the width or height of its children to fill the available space in the best possible way on different screen sizes.

Many designers and developers find this flexbox layout easier to use, as positioning of the elements is simpler thus more complex layouts can be achieved with less code, leading to simpler development process. Flexbox layout algorithm is direction based unlike the block or inline layout which are vertically and horizontally based. This flexbox layout should be used for small application components, while new CSS Grid Layout Module is emerging to handle the large scale layouts.

Rather that explaining how the flex properties work, this guide will focus on how the flex properties affect the layout in a visual way.

Basics

Before we start with describing the flexbox properties let’s give a little introduction of the flexbox model. The flex layout is constituted of parent container referred as flex container and its immediate children which are called flex items.

CSS3-Flexbox-Model

In the box above you can see the properties and the terminology used to describe the flex container and its children. For more information on their meaning read the official flexbox model by W3C.

The flexbox layout went through many iterations and several syntax changes from its initial draft in 2009, so to avoid confusion and make everything clear we’ll use only the syntax from the last working draft (Sep 2014). If you need to maintain old browser compatibility you can read this article on how to do that in the best way.

The browser support for the latest flexbox specification is:

  • Chrome 29+
  • Firefox 28+
  • Internet Explorer 11+
  • Opera 17+
  • Safari 6.1+ (prefixed with -webkit-)
  • Android 4.4+
  • iOS 7.1+ (prefixed with -webkit-)

You can see detailed browser support and compatibility here.

Usage

To use flexbox layout just set the display property on the parent HTML element:

.flex-container {
  display: -webkit-flex; /* Safari */
  display: flex;
}

Or if you want to display it like an inline element use:

.flex-container {
  display: -webkit-inline-flex; /* Safari */
  display: inline-flex;
}

Note: This is the only property you need to set on the parent container and all its immediate children will become automatically flex items.

There are several ways to group the flexbox properties and by far the easiest way I’ve found to understand the flexbox options and their usage is to divide them in two groups one for the flex container and one for the flex items. Below are explained all of them and how they affect the layout visually.

Flexbox container properties

flex-direction

This property specifies how flex items are laid out in the flex container, by setting the direction of the flex container’s main axis. They can be laid out in two main directions, like rows horizontally or like columns vertically.

Values:

.flex-container {
  -webkit-flex-direction: row; /* Safari */
  flex-direction:         row;
}

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

.flex-container {
  -webkit-flex-direction: row-reverse; /* Safari */
  flex-direction:         row-reverse;
}

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

.flex-container {
  -webkit-flex-direction: column; /* Safari */
  flex-direction:         column;
}

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

.flex-container {
  -webkit-flex-direction: column-reverse; /* Safari */
  flex-direction:         column-reverse;
}

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

Default value: row

Note: row and row-reverse are dependent of the writing mode so in rtl context they will be reversed respectively.

flex-wrap

The initial flexbox concept is the container to set its items in one single line. The flex-wrap property controls if the flex container lay out its items in single or multiple lines, and the direction the new lines are stacked in.

Values:

.flex-container {
  -webkit-flex-wrap: nowrap; /* Safari */
  flex-wrap:         nowrap;
}

Flex items are displayed in one row, by default they are shrunk to fit the flex container’s width flexbox flex-wrap nowrap

.flex-container {
  -webkit-flex-wrap: wrap; /* Safari */
  flex-wrap:         wrap;
}

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

.flex-container {
  -webkit-flex-wrap: wrap-reverse; /* Safari */
  flex-wrap:         wrap-reverse;
}

Flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top flexbox flex-wrap wrap-reverse

Default value: nowrap

Note: These properties are dependent of the writing mode so in rtl context they will be reversed respectively.

flex-flow

This property is a shorthand for setting the flex-direction and flex-wrap properties.

Values:

.flex-container {
  -webkit-flex-flow: <flex-direction> || <flex-wrap>; /* Safari */
  flex-flow:         <flex-direction> || <flex-wrap>;
}

Default value: row nowrap

justify-content

The 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-container {
  -webkit-justify-content: flex-start; /* Safari */
  justify-content:         flex-start;
}

Flex items are aligned to the left side of the flex container in ltr context flexbox justify-content flex-start

.flex-container {
  -webkit-justify-content: flex-end; /* Safari */
  justify-content:         flex-end;
}

Flex items are aligned to the right side of the flex container in ltr context flexbox justify-content flex-end

.flex-container {
  -webkit-justify-content: center; /* Safari */
  justify-content:         center;
}

Flex items are aligned at the center of the flex container flexbox justify-content center

.flex-container {
  -webkit-justify-content: space-between; /* Safari */
  justify-content:         space-between;
}

Flex items are displayed with equal spacing between them, first and last flex items are aligned to the edges of the flex container flexbox justify-content space-between

.flex-container {
  -webkit-justify-content: space-around; /* Safari */
  justify-content:         space-around;
}

Flex items are displayed with equal spacing around every flex item, even the first and last flex items flexbox justify-content space-around

Default value: flex-start

align-items

Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. This property sets the default alignment for all flex items, including the anonymous ones.

Values:

.flex-container {
  -webkit-align-items: stretch; /* Safari */
  align-items:         stretch;
}

Flex items fill the whole height (or width) from cross start to cross end of the flex container flexbox align-items stretch

.flex-container {
  -webkit-align-items: flex-start; /* Safari */
  align-items:         flex-start;
}

Flex items are stacked to the cross start of the flex container flexbox align-items flex-start

.flex-container {
  -webkit-align-items: flex-end; /* Safari */
  align-items:         flex-end;
}

Flex items are stacked to the cross end of the flex container flexbox align-items flex-end

.flex-container {
  -webkit-align-items: center; /* Safari */
  align-items:         center;
}

Flex items are stacked to the center of the cross axis of the flex container flexbox align-items center

.flex-container {
  -webkit-align-items: baseline; /* Safari */
  align-items:         baseline;
}

Flex items are aligned in a way that their baselines are aligned flexbox align-items baseline

Default value: stretch

Note: Read more details about how baselines are calculated here.

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-container {
  -webkit-align-content: stretch; /* Safari */
  align-content:         stretch;
}

Flex items are displayed with distributed space after every row of flex items flexbox align-content stretch

.flex-container {
  -webkit-align-content: flex-start; /* Safari */
  align-content:         flex-start;
}

Flex items are stacked toward the cross start of the flex container flexbox align-content flex-start

.flex-container {
  -webkit-align-content: flex-end; /* Safari */
  align-content:         flex-end;
}

Flex items are stacked toward the cross end of the flex container flexbox align-content flex-end

.flex-container {
  -webkit-align-content: center; /* Safari */
  align-content:         center;
}

Rows of flex items are stacked in the center of the cross axis of the flex container flexbox align-content center

.flex-container {
  -webkit-align-content: space-between; /* Safari */
  align-content:         space-between;
}

Rows of flex items are displayed with equal spacing between them, first and last rows are aligned to the edges of the flex container flexbox align-content space-between

.flex-container {
  -webkit-align-content: space-around; /* Safari */
  align-content:         space-around;
}

Flex items are displayed with equal spacing around every row of flex items. flexbox align-content space-around

Default value: stretch

Note: This property has only effect when the flex container has multiple lines of flex items. If they are placed in single line this property has no effect on the layout.

Note for flex containers

  • 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.

Flexbox item properties

order

The order property controls the order in which children of a flex container appear inside the flex container. By default they are ordered as initially added in the flex container.

Values:

.flex-item {
  -webkit-order: <integer>; /* Safari */
  order:         <integer>;
}

Flex items can be reordered with this simple property, without restructuring the HTML code flexbox order

Default value: 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 in the flex container when positive free space is distributed.

Values:

.flex-item {
  -webkit-flex-grow: <number>; /* Safari */
  flex-grow:         <number>;
}

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

Default value: 0

Note: 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 in the flex container when negative free space is distributed.

Values:

.flex-item {
  -webkit-flex-shrink: <number>; /* Safari */
  flex-shrink:         <number>;
}

By default all flex items can be shrunk, but if we set it to 0 (don’t shrink) they will maintain the original size flexbox flex-shrink

Default value: 1

Note: Negative numbers are invalid.

flex-basis

This property takes the same values as the width and height properties, and specifies the initial main size of the flex item, before free space is distributed according to the flex factors.

Values:

.flex-item {
  -webkit-flex-basis: auto | <width>; /* Safari */
  flex-basis:         auto | <width>;
}

flex-basis is specified for the 4th flex item and dictates the initial size of the element flexbox flex-basis

Default value: auto

Note: There is a naming issue with the auto value which will be resolved in future.

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).

.flex-item {
  -webkit-flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ]; /* Safari */
  flex:         none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
}

Default value: 0 1 auto

Note: 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:

.flex-item {
  -webkit-align-self: auto | flex-start | flex-end | center | baseline | stretch; /* Safari */
  align-self:         auto | flex-start | flex-end | center | baseline | stretch;
}

The 3rd and 4th flex items have overridden alignment through the align-self property flexbox align-self

Default value: auto

Note: The value of auto for align-self computes to the value of align-items on the element’s parent, or stretch if the element has no parent.

Note for flex items

  • float, clear and vertical-align have no effect on a flex item, and do not take it out-of-flow.

Flexbox playground

Here’s a flex playground where you can play with the different flex properties and explore the power of the flexbox layout. Combine several flex properties to get complex layouts.

See the Pen Flexbox Properties Demonstration by Dimitar (@justd) on CodePen.

You can also see it full page here or get the source code at GitHub.

Dimitar Stojanov

Dimitar is regular guy passionate about helping others, that's why he built Invoicebus, a service for designers and developers where they can create and track their invoices and payments in a beautiful and simple manner.