Flexbox

Menu
Menu

Flexbox and Display

Modern browsers support the display property of flex. This converts the element to what is known as a flex-container. Immediate child elements inside that container are now known as flex-items. How the flex-items 'flex' into the space of the flex-container can be controlled. This is great for creating layouts.

Flex-containers and Flex-items

To see how flexbox works take a simple HTML structure of:

The above has a parent <div> with three immediate children.

By making the parent <div> a flex-container with display:flex, the three child elements become flex-items.

This results in:

Flex Item 1
Flex Item 2
Flex Item 3

Experiment with this in CodePen

Flex-container and Flex-item Properties

Both flex-containers and flex-items have a range of properties to allow manipulation of the flex behaviour. Reading the full list without some context can be daunting, so we will cherry pick the most used properties.

justify-content

If you view the above in CodePen you will see there is actually more CSS properties in play (to make the demo easier on the eye).

Firstly note that, without other properties in play, the width of a flex-item will match its content. Switch off the flex-item property of flex:1 1 33% and the items will appear aligned to the left with space to the right. This space in the flex-container is available for the flex-items to 'flex' into.

Given we now have space in the flex-container we can use the justify-content to control the placement of the flex-items.

The CSS property justify-content is used to control spacing between and around items along the main axis (assuming extra space is available). It is applied to the flex-container items.

Try adding the following to the CodePen:

The other justify-content options to experiment with are:

flex-start
The default value. Items are packed flush to each other toward the starting edge of the flex-container.
flex-end
Items are packed flush to each other toward the ending edge of the flex-container.
center
Items are packed flush towards the centre of the flex-container.
space-between
Items are evenly distributed within the flex-container along the main axis. The spacing between items is the same. The first item is flush with the main-start edge, and the last item is flush with the main-end edge.
space-around
Items are evenly distributed within the flex-container along the main axis. The spacing between items is the same. The empty space before the first and after the last item equals half of the space between each pair of adjacent items.

Width of Flex-items

The width of flex-items can depend on a number of factors. The most important factor is the actual content of the container. Be conscious of the fact that the flex-item will expand to fit any content such as an image.

The width is also impacted by the width of the flex-container, especially if that is of a fixed width.

The flex-items can also be set to shrink or grow into any 'flex space' available in the flex-container. This behaviour can also be enabled or prevented via the flex-shrink and flex-grow properties respectively.

Also, you may reasonably assume that you can set the width property of a flex-item. This can be done but it is better to use the flex-basis property.

The flex-basis property sets the initial size of a flex-item before flexbox distributes any 'flex space' available in the flex-container.

More commonly the shorthand flex property is used by developers as it allows flex-grow, flex-shrink and flex-basis to be set in one go.

Tip: When working with Google Chrome the Dev Tools provide a briliant way to experiment with flex.

Chrome Dev Tools with Flexbox

Remove the justify-content from the CodePen and use a flex-item property instead. As we want our flex-items to grow and fill all space available we could use:

Here the flex-items are set to grow and shrink aiming for 33% of the space available.

Main and Cross Axis plus flex-direction

We have seen that by default the flex-items will try to fit in horizontally using the 'flex space' available. This is due to the flexbox concept of the ‘main’ and ‘cross’ axis. By default the main axis is horizontal and the cross axis vertical.

Flexbox Directions

We can change this with the flex-direction property.

The above would result in:

Flex Item 1
Flex Item 2
Flex Item 3

Both row and column have reverse values of row-reverse and column-reverse which change the flow of the flex-items to right to left and bottom to top respectively.

flex-wrap

By default, flex-items will try to fit onto one line. You can allow items to wrap onto multiple lines using the flex-wrap property.

Other values for flex-wrap include nowrap (default) and wrap-reverse.

Experiment with this CodePen to see the use of flex-wrap.

Spacing Flex Items with gap

Very handy property (that took a while to settle into the standard but now widely supported) that allows gaps or gutters to be applied. It removes the need for paddings and margins when working with flexbox. Gaps can be applied both columns and rows with column-gap and row-gap, or in shorthand with gap and two values, row and then column. If one value supplied, the value is used for both colum and row gaps.

Experiment with gap with this CodePen.

Flex Playgrounds and Examples