Flexbox

The CSS Flexible Box Module (Flexbox) is a positioning system introduced in CSS3 for making one-dimensional content (rows and columns) simpler to produce.

The axis and creating a flexible box

Flexbox is designed for producing one-dimensional content, that content runs along a main axis which may be a row or column (forward or in reverse). The direction of the axis is decided with the flex-direction property:

  • row: The default layout, flex children are laid out in a row as if they are inline-block elements
  • row-reverse: Items are laid out in a reversed row
  • column: Items are laid out in a column, as if each child is a block element
  • column-reverse: Items are laid out in a reversed column

The main axis

The main axis of a flexible box is that chosen by the flex-direction property, but to be a flexible box it must also have the display type of flex applied to make the direct children flex items:

<-------- Main axis (flex-direction: row) -------->

The cross axis

The cross axis is the opposite to the main axis, so if flex-direction is set to row then the cross-axis is vertical.

Cross axis (flex-direction: row)

The default settings

As with most CSS properties, defaults are defined and applied to give a consistent experience across browsers. These are as follows:

  • The default flex-direction is row
  • Items start at the starting edge of the main axis (left-to-right for a default row in English, but right-to-left for a default row in Arabic)
  • Items cannot be stretched along the main-axis, but can be shrunk
  • Items stretch to fill the size of the cross-axis, this gives even heights to flex items in a row or equal widths in a column
  • flex-wrap is set to nowrap, meaning items do not wrap onto a new row by default should the screen become too small for the items
  • flex-basis is set to auto, this defines how the flex items should shrink and grow in size in response to changes in size of the parent flex container

Allowing wrapping

Often, we will want content to wrap onto a new row should the content be too large for the viewports width. We can do this by setting flex-wrap to wrap:

Try resizing the screen to see how the boxes automatically wrap onto a newline as the screen becomes smaller.

We can also make use of the shorthand flex-flow property to specify the values for flex-direction and flex-wrap respectively:

Flex item properties

There are three main properties for controlling how flex items appear in the flexible box:

flex-grow
The flex-grow property is used to specify a growth factor, as a positive integer, for a flex-item. If there was a flexible box of width 1000px containing ten items of width 50px, setting flex-grow: 1 would share all the remaining space equally and become 100px each in size. If we gave 1 of the items a flex-grow value of 2, that would receive two parts of the available space (100px) instead of sharing equally with the rest of the elements.
flex-shrink
The flex-shrink property controls how space is taken away from an element. Setting a positive integer allows a flex item to shrink smaller than the defined flex-basis. The larger the value, the faster a flex item will shrink.
flex-basis
The flex-basis property decides upon the size of an item in relation to available space in the flexible box it is contained in. The initial value is auto, which gets its width from one of two locations:
  • If a width is defined, that is the flex-basis of the item
  • If no width is defined, the width of the content is the flex-basis of the item

These properties are commonly combined into the shorthand flex property instead:

flex: flex-grow flex-shrink flex-basis;

The following example demonstrates three boxes which will grow and shrink as their container shrinks, always growing to fill the containers total length:

Box 1
Box 2
Box 3 has more content
Box 4 is here
Box 5
Box 6
Setting flex: 1 1 auto; is the same as setting flex: auto;

If we did not want items to grow to fill the remaining space, we can set the flex-grow property to 0:

Box 1
Box 2
Box 3 has more content
Box 4 is here
Box 5
Box 6

Setting the flex-basis to 0, flex-grow and flex-shrink to 1 will result in flex items which grow and shrink to fill the given space equally:

Box 1
Box 2
Box 3 has more content
Box 4 is here
Box 5
Box 6

A flexible grid

Flexbox can also be used to create grids of content, this requires a container element with display: flex and flex-direction: column applied for containing rows of content. Each container will contain row elements, with display: flex and wrapping behaviour applied. Each column is then created with a specific flex-basis, col-6 would have a flex-basis: 50% on a 12-column grid for example:

Box 1

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

Box 2

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

Box 3

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

Box 4

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

Box 5

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

Box 6

Placeholder image

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque esse veritatis officiis sunt eligendi beatae ducimus sapiente laudantium non aliquam!

A media query is used to change the flex-basis dependent on the screen size, any column below 1024px in screen width will have a flex-basis: 100%.

This Flexbox grid could then be used to create different page layouts, such as the holy grail layout:

Navbar

Side menu

Main content

Lorem ipsum dolor sit amet consectetur adipisicing elit. Assumenda numquam enim aut? Aspernatur nemo eligendi saepe, impedit, error accusantium cupiditate magnam doloribus dolor in a! Aperiam quis a magni error.

Side menu

Footer