Flexbox

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

In this picture 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:

 

<div class=”flex-container”>
<div class=”flex-item”>1</div>
<div class=”flex-item”>2</div>
<div class=”flex-item”>3</div>
<div class=”flex-item”>4</div>
</div>

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

 

.flex-container {
display: flex;
}

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

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.

 

.flex-container {
flex-direction: row;
}

flex-container-1

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

.flex-container {
flex-direction: row-reverse;
}

flex-container-2

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

.flex-container {
flex-direction: column;
}

 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.

.flex-container {
flex-direction: column-reverse;
}

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.

.flex-container {
flex-wrap: nowrap;
}

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-container {
flex-wrap: wrap;
}

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-container {
flex-wrap: wrap-reverse;
}

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

.flex-container {
flex-flow: <flex-direction> || <flex-wrap>;
}

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

.flex-container {
justify-content: flex-start;
}

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-container {
justify-content: flex-end;
}

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-container {
justify-content: center;
}

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

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

.flex-container {
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.

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-container {
justify-content: space-around;
}

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-container {
align-items: stretch;
}

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-container {
align-items: flex-start;
}

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-container {
align-items: flex-end;
}

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-container {
align-items: center;
}

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-container {
align-items: baseline;
}

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

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-container {
align-content: flex-start;
}

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-container {
align-content: flex-end;
}

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

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

.flex-container {
align-content: center;
}

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.

.flex-container {
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.

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-container {
align-content: space-around;
}

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 the same as the others.

ss

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

.flex-item {
order: <integer>;
}

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.

 

.flex-item {
flex-grow: <number>;
}

If all flex items have same value for flex-grow than all items have same size in the container.

If all flex items have the same value for flex-grow than all items have the 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.

 

.flex-item {
flex-shrink: <number>;
}

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.

 

.flex-item {
flex-basis: auto | <width>;
}

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

 

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

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

 

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

All flex items have overridden alignment through the align-self property.

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

Review

In this lesson we have learned Flexbox, which provides us with a box model optimized for laying out user interfaces. To use Flexbox we need to set the display property to flex on parent element. All immediate child elements (.flex-item) are automatically set to flex items.

These are parent element properties of Flexbox:

  • flex-direction 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.
  • flex-wrap tell the container to lay out its items in single or multiple lines, and the direction the new lines are stacked in.
  • flex-flow property is a shorthand flex-direction and flex-wrap properties.
  • justify-content property aligns flex items along the main axis of the current line of the flex container.
  • align-items property defines how flex items are laid out along the cross axis on the current line.
  • align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis.

Flexbox Item Properties are as follows:

  • order property control the order in which they appear in the flex container.
  • flex-grow specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items.
  • flex-shrink specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items.
  • flex-basis takes the same values as the width and height properties, and specifies the initial main size of the flex item.
  • flex 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).
  • align-self property allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.