Introduction

When creating site layouts, a number of trivial problems related to aligning and placing items on a page often need solving. There are multiple solutions to these problems, but they often require many code lines and are not universal. Flexbox specification was implemented in CSS3. It makes developers’ life easier when they are tasked to develop page layouts.

About the article

This article is intended for developers who have experience in HTML and CSS, as well as development of websites with adaptive web design.

This article discusses the concept of Flexbox: what this module is used for, its main properties, examples of use, advantages and disadvantages of using this approach. A comparative analysis of Flexbox and other tools is also given.

Description

Flexbox (CSS Flexible Box Layout Module) is a CSS module created for horizontal and vertical alignment, setting out the direction and order of items in a container, even when their size is unknown or changes dynamically. Flexbox combines many properties that make the task of creating responsive layouts easier. A distinctive feature of Flexbox is the possibility to resize all nested html elements to fill the entire available area of the parent element as much as possible. You can also make all the columns in the layout the same height, even if the content size in them is different.

Use

To start using Flexbox features, you need to define the html element as a flex container. To create a flex container, set one of the following values to the display parameter:

  • flex — if the width of items is insufficient, the content may extend beyond the container boundaries.
  • inline-flex — the priority is given to the content (the size of items is changed to the necessary width so that they fit in the container if possible).

All html elements inside a flex container are child elements.

Let’s consider the basic properties of Flexbox specification.

Flex container properties

flex-direction

In a flex container, all child elements are located along one of the axes:

In a flex container, all child elements are located along one of the axes

  • The main axis is the axis passing in the direction along which flex elements are arranged. The start of this axis is called the main start, and the end — the main end.
  • The cross axis is the axis perpendicular to the main axis. The axis start is the cross start, and the axis end is the cross end.

Use the flex-direction property to specify the main axis along which child items will be arranged.

This property has the following values:

  • row — items are arranged along the main axis from left to right (default value).

Example entry:

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

  • row-reverse — items are arranged along the main axis from right to left.

Example entry:

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

  • column and column-reverse — items are located along the cross axis. If the column parameter is used — from top to bottom, and if the column-reverse parameter is used — from bottom to top.

Example entries:

Left column:

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

Right column:

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

justify-content

This property defines the alignment of items relative to the main axis. It has the following values:

  • flex-start — items are aligned relative to the start of the main axis (default value).

Example entry:

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

  • flex-end — items are aligned relative to the end of the main axis.

Example entry:

.flex-container {
display: flex
justify-content: flex-end;
}

  • center — items are aligned relative to the center of the main axis.

Example entry:

.flex-container {
display: flex
justify-content: center;
}

  • space-between — the first item is located at the start of the main axis, the last item is located at the end of the main axis, the remaining items are evenly distributed in the remaining space.

Example entry:

.flex-container {
display: flex
justify-content: space-between;
}

  • space-around — items are evenly distributed along the main axis.

Example entry:

.flex-container {
display: flex
justify-content: space-around;
}

align-items

This parameter determines the alignment of items relative to the cross axis.

Available values:

  • flex-start — items are aligned relative to the start of the cross axis.

Example entry:

.flex-container {
display: flex
align-items: flex-start;
}

  • flex-end — items are aligned relative to the end of the cross axis.

Example entry:

.flex-container {
display: flex
align-items: flex-end;
}

  • center — items are aligned relative to the center of the cross axis.

Example entry:

.flex-container {
display: flex
align-items: center;
}

  • baseline — items are aligned along the baseline of the cross axis.

Example entry:

.flex-container {
display: flex
align-items:baseline;
}

  • stretch — items are stretched and occupy the entire space along the cross axis (default value).

Example entry:

.flex-container {
display: flex
align-items: stretch;
}

flex-wrap

Items inside a flex container can be arranged in a single line or a set of lines. The flex-wrap property is used to set this parameter.

Available values:

  • nowrap — items are placed in a single line (default value).

Example entry:

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

  • wrap — multiline item layout mode.

Example entry:

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

  • wrap-reverse — multiline mode for arranging items. Items are arranged in reverse order.

Example entry:

.flex-container {
display: flex
flex-wrap: wrap-reverse;
}

flex-flow

The flex-flow property allows setting the direction of items along one of the axes and the multiline mode of items layout (flex-direction and flex-wrap).

Example of a full entry:

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

Short entry:

.flex-container {
flex-flow: row wrap;
}

align-content

The align-content property is used to control the alignment of lines relative to the cross axis. This property only works in the multiline mode (flex-wrap: wrap; or flex-wrap: reverse-wrap;). Available values:

  • flex-start — lines are aligned relative to the start of the cross axis.

Example entry:

.flex-container {
display: flex
align-content: flex-start;
}

  • flex-end — lines are aligned relative to the end of the cross axis.

Example entry:

.flex-container {
display: flex
align-content: flex-end;
}

  • center — lines are aligned relative to the center of the cross axis.

Example entry:

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

  • space-between — the first line of items is located at the start of the cross axis, the last line of items — at the end of the cross axis, the remaining lines are evenly distributed in the remaining space.

Example entry:

.flex-container {
display: flex
align-content: space-between;
}

  • space-around — lines of items are evenly distributed from the start to the end of the cross axis.

Example entry:

.flex-container {
display: flex
align-content: space-around;
}

  • stretch — lines of items are stretched and occupy the entire space along the cross axis (default value).

Example entry:

.flex-container {
display: flex
align-content: stretch;
}

Properties for flex container child elements

flex-basis

This property sets the initial item size relative to the main axis. To set the flex-basis value, length units (px, em, %, etc.) or auto (default) are used. See the example below. flex-basis: 200px; is set for the green item, and flex-basis: 100px; — for the blue ones:

Example entry:

.item 1 {
flex-basis: 100px;
}

flex-grow

It determines how many times an item can be larger than the neighboring items. This property is set with a number (0 is default). Below there is an example, in which flex-grow: 2; is set for the green item, the width of the blue items is 100px, i.e. the width of the green item will be 2 times larger (200px):

Example entry:

.item 1{
flex-grow: 2;
}

flex-shrink

The flex-shrink property determines how many times the item will shrink relative to the neighboring items, if there is not enough space. This property is set with a number (1 is default). In the example below flex-shrink: 5; is set for the green item:

Example entry:

.item 1 {
flex-shrink: 5;
}

flex

This property is a short entry for the flex-grow, flex-shrink, and flex-basis properties.

Example of a full entry:

.flex-container {
flex-grow: 2;
flex-shrink: 4;
flex-basis: 100px;
}

Short entry with flex:

.flex-container {
flex: 2 4 100px;
}

align-self

This property is used to align the item relative to the cross axis.

This property has the following values:

  • auto — default value. The item uses flex container align-items.

Example entry:

.flex-item:hover {
align-self: auto
}

  • flex-start — the item is located relative to the start of the cross axis.

Example entry:

.flex-item:hover {
align-self: flex-start
}

  • flex-end — the item is located relative to the end of the cross axis.

Example entry:

.flex-item:hover {
align-self: flex-end
}

  • center — the item is located in the center of the cross axis.

Example entry:

.flex-item:hover {
align-self: center
}

  • baseline — the item is aligned with the baseline of the cross axis.

Example entry:

.flex-item:hover {
align-self: baseline
}

  • stretch — the item is stretched and occupies the entire space along the cross axis.

Example entry:

.flex-item:hover {
align-self: stretch/*растягиваем при наведении*/
}

order

In a flex container, items are arranged one after another, in the order specified using html. However, this order can be changed. The order property is used for that. This property sets the sequence number of the element position. The value is set as an integer (0 is default). In the example below, order: 2; is set for the green item, and order: 1; — for the blue items, and since the position of the green item is more important than the position of the rest items, it is located at the end:

Example entry:

.item 1 {
order: 2
}
.item 3 {
order: 1
}

Advantages of using Flexbox

  1. Items easily become adaptive depending on the available space and properties.
  2. Vertical and horizontal alignment of items.
  3. Flexible control of the location of items without changing their order in html code.
  4. Items can be automatically aligned in multiple lines/columns taking up all the free space.
  5. Simple adaptation of the html page to languages with right-to-left spelling and automatic arrangement of html elements in the correct order.
  6. Simple and understandable syntax that gets mastered quite quickly.

Browser support

Flexbox is supported by all modern browsers.

Browsers that support Flexbox

Comparison with other tools

Grid Layout

CSS Grid Layout represents a two-dimensional grid for CSS. Grid Layout can be used to place main page areas or small UI elements.

Grid Layout is an intersecting set of horizontal and vertical lines: one set defines columns and the other one — lines. Elements can be placed in the grid according to the lines and columns.

Grid Layout vs Flexbox
  • Grid Layout is great for the creation of large elements of the site. This approach makes it easier to manage the page layout and create asymmetric projects. Flexbox is great for aligning the content inside elements. It is most often used to place small details of the project.
  • Grid Layout is used for creating 2D layouts (work with lines and columns). Flexbox works better in only one dimension (lines or columns).

Examples of placing multiple items using Flexbox and Grid Layout:

Flexbox:

<div class=“wrapper“>
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>

.wrapper {
display: flex;
flex-wrap: wrap;
}
.wrapper > div {
flex: 1 1 200px;
}

Grid Layout:

<div class=”wrapper”>
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>

.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}

  • Flexbox is way ahead of Grid Layout in browser support. Grid Layout is new and the issue of browser support is still pressing as opposed to Flexbox.

Grid Layout and Flexbox are mainly used as complementary tools.

Float Layout

It is a method of creating webpage markup based on the float property. Essentially, the float property takes the element, removes it from the normal page flow, and positions it to the left or right of the parent element. All other elements on the page will wrap around this element. For example, paragraphs will wrap the image if the float property is set for the <img> element.

When the float property is applied to multiple elements at the same time, it allows creating a layout with wrapped elements arranged side by side or opposite to each other.

Float Layout vs Flexbox
  • Multiline markup. Using float, elements can only be placed on the left edge (using float: left;) or on the right edge (using float: right;) with the need to invert the order of the elements. In Flexbox, it is achieved by installing the flex-wrap: wrap; or flex-wrap: wrap-reverse; container.
  • Arrangement of elements in a column. You can’t use the float property to set the location of elements in a column. Flexbox offers this option — flex-direction: column; or flex-direction: column-reverse;.
  • You cannot use the float property to horizontally center elements. In Flexboxjustify-content: center;.
  • To place the elements on the right side, you should invert them in the markup (locate them in reverse order) by setting float: right; to them. For a flexbox container, just set justify-content: flex-end; and you will not need to reverse the order of the markup.
  • In Float Layout, there is no way to change the layout of elements without changing the markup. You can use Flexbox to either invert the location of elements by setting flex-direction: row-reverse; to the container, or set the order parameter to the flex element:
  • Float cannot guarantee that elements will be located in the same line. In Flexbox, this behavior is set by default (flex-wrap: nowrap; is set by default), and elements will not be carried forward to a new line unless flex-wrap: wrap; (or, in rare cases, flex-wrap: wrap-reverse;) is set to the container.
  • There is no way to control the vertical position of elements. Everything is aligned “on top” without being able to influence it. It is also not possible to set the same height to elements without setting a fixed height for all. In Flexbox, you can set the vertical position both for all elements, and for a single element. All elements — set align-items to the container, a single element — set align-item to the element.

Conclusion

Flexbox makes it possible to easily solve a number of problems related to creating site layouts. It has a set of smart defaults that allow creating complex layouts using a relatively small number of code lines.

Useful links

FlexBox Cheat Sheet (CSS3 Flexible Box)
Why Start Using Flexbox
Flexbox Myth Busting
Flexbox Froggy — A Game to Learn CSS Flexbox
Flexbox Generator
Flexbugs