The Ultimate Guide to Flexbox

Overview

The Flexbox Layout officially recognized as CSS Flexible Box Layout Module is a new layout model in CSS3.

Flexbox is a single dimensional layout, which means that it lays items in one dimension at a time, either as a row, or as a column, but not both together. This can be opposed to the two-dimensional model - CSS Grid Layout, which lays the items in two dimensions simultaneously (rows and columns together).

Flexbox was introduced as an alternative to CSS Floats for setting the overall appearance of a webpage. Flexbox comes with many benefits, in particular, with it you can control alignment, direction, order, and size of items.

The items inside a flex container:

  • can be organized in any direction (leftwards, rightwards, downwards or even upwards) (flex-direction).
  • can have direct (left-to-right) or reversed (right-to-left) order.
  • can have “flex” width and height to fill the available space (flex-item).
  • can be set to dynamically collapse or expand along the main axis, and in the meantime preserve the size of the secondary cross axis.
  • can be organized linearly along the main axis or wrapped into multiple lines along or across the cross axis.

Flexbox is relatively new, but it enjoys excellent browser support today (nearly 83% of browsers support it).

(Learn more about browser support and compatibility).

Flexbox Basics

When working with Flexbox you need to think in terms of two axes — the main axis and the cross axis, and should differentiate between flex containers and flex items.

Main and Cross Axis

Flexbox is a single-axis–oriented, it has main axis and cross axis . It means that items are laid either along the main axis, or cross axis. The cross axis is always perpendicular to the main one.

The main axis is defined by the flex-direction property, which has the following values:

  • row
  • row-reverse
  • column
  • column-reverse

If the flex-direction property is specified with row or row-reverse values, then your main axis will be horizontal, i.e. run along the row in the inline direction. And the cross axis will run down the columns.

flex-row

If the flex-direction property is specified with column or column-reverse values, then the main axis will be vertical, i.e. runs from the top of the page to the bottom in the block direction. As for the cross axis, it will run along the rows.

flex-column

Have a look at this figure to get a better understanding of the concept behind Flexbox axis.

flexbox-axis

  • main axis- The main axis of a flex container is the main axis along which flex items are placed.
  • main-start | main-end - The flex items are laid out within the container starting from main-start and going to main-end.
  • main size - A flex item's width or height in the main dimension is the item's main size.
  • cross axis - The axis perpendicular to the primary axis which direction depends on the main axis direction (horizontal or vertical).
  • cross-start | cross-end - Flex lines are filled with items and put 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 in the cross dimension is the item's cross size.
Source: W3.org

Flex Containers and Items

Flex container is a parent element, which groups a bunch of children elements, flex items. In most cases, the container defines layout and position of its flex items, however, flex items can be manipulated individually.

container-items

To turn an HTML element to Flex container you should use display property with flex (block-level flex container box) or inline-flex (defines inline-level flex container box) values. Otherwise, the browser would ignore all the flexbox properties you used.

.container {
  display: flex; /* or inline-flex*/
}
Note, that some browsers do not support display:flex, use prefixes listed below.
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box;    /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER */
display: -webkit-flex;     /* NEW - Chrome */
display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+

Flex Container Properties

The flex-direction property

The flex-direction property is used for creating row and column layouts. It specifies the directions of the flex container’s main axis and sets the order in which items appear.

The flex-direction property has the following values:

  • row - items are displayed along the row from left to right.
  • row-reverse - items are displayed along the right to left.
  • column - items are displayed vertically from top to bottom.
  • column-reverse - items are displayed vertically from bottom to top.

flex-direction

Example of the flex-direction property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      h3 {
        color: #8ebf42;
      }
      .flex-container {
        display: flex;
        flex-direction: row-reverse;
        padding: 30px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 80px;
        height: 70px;
        margin: 5px;     
        border-radius: 3px;
        background-color: #1faadb;
      }
    </style>
  </head>
  <body>
    <h3>row-reverse</h3>
    <div class="flex-container">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </body>
</html>

In our example the items are organized in a reversed order. Change values of flex-direction property (row, column, column-reverse) to see how the appearance of the items changes.

Note: row and row-reverse are dependent of the writing mode, so in rtl (right-to-left) context they will be reversed respectively.

The flex-wrap property

By default, all the flex items fit onto one line, and if flex items are too wide for the container, they will overflow it. To prevent this you should use the flex-wrap property to wrap the items.

The property can accept the following values:

  • nowrap (default) - flex items are displayed in one line, by default they fit the flex container's width.
  • wrap - flex items are displayed in multiple rows if needed from left-to-right and top-to-bottom.
  • wrap-reverse - flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top.

flex-wrap

Note: The property depends on the writing mode, so in rtl (right-to-left) context they will be reversed respectively.

The justify-content property

The justify-content property is used to define the horizontal alignment of items along the main axis. It helps distribute free space left between the flex items on the main axis.

The values for justify-content are as follows:

  • flex-start (default value) - items are laid out at the beginning of the container.
  • flex-end - items are laid out at the end of the container.
  • center - items are laid out at the center of the container.
  • space-between - items are evenly (with space between them) distributed in the line; first item is on the start line, last item on the end line.
  • space-around - items are displayed with space before, between, and after.
  • space-evenly - items are distributed so that the spacing between any two items (and the space to the edges) is equal.

justify-content

Example of the justify-content property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        padding: 10px;
        margin-bottom: 20px;
        background-color: #1faadb;
      }
      .flex-start {
        justify-content: flex-start;
      }
      .flex-end {
        justify-content: flex-end;
      }
      .center {
        justify-content: center;
      }
      .space-between {
        justify-content: space-between;
      }
      .space-around {
        justify-content: space-around;
      }
      .flex-start {
        justify-content: flex-start;
      }
      .flex-container > div {
        width: 28%;
        height: 45px;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
      }
      .flex-container > div.item-two {
        width: 18%;
      }
    </style>
  </head>
  <body>
    <p>flex-start</p>
    <div class="flex-container flex-start">
      <div></div>
      <div class="item-two"></div>
      <div></div>
    </div>
    <p>flex-end</p>
    <div class="flex-container flex-end">
      <div></div>
      <div class="item-two"></div>
      <div></div>
    </div>
    <p>center</p>
    <div class="flex-container center">
      <div></div>
      <div class="item-two"></div>
      <div></div>
    </div>
    <p>space-between</p>
    <div class="flex-container space-between">
      <div></div>
      <div class="item-two"></div>
      <div></div>
    </div>
    <p>space-around</p>
    <div class="flex-container space-around">
      <div></div>
      <div class="item-two"></div>
      <div></div>
    </div>
  </body>
</html>

Change the value of justify-content property to see how the items are aligned.

The align-items property

The align-items property is used for aligning items along the cross axis. It is just the opposite to justify-content property, which aligns the items along the main axis.

The values for align-items are as follows:

  • stretch (default) - items are stretched to fill the container.
  • flex-start - items are stacked to the cross start of the container.
  • flex-end- items are stacked to the cross end of the container.
  • center- items are stacked at the center of the cross axis.
  • baseline - items are aligned just as their baselines are aligned.

align-items

Note: If the flex container’s height is constrained, the stretch value may cause the contents of the flex item to overflow the item.

Example of the align-items property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        justify-content: space-between;
        align-items: center; /* Use another value to see the result */
        height: 250px;
        padding: 15px;
        background-color: #1faadb;
      }
      .flex-container > div {
        width: 15%;
        height: 100%;
        border-radius: 3px;
        background-color: #8ebf42;
      }
      .flex-container .one {
        height: 60%;
      }
      .flex-container .three {
        height: 40%;
      }
      .flex-container .four {
        height: 70%;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div class="one"></div>
      <div class="two"></div>
      <div class="three"></div>
      <div class="four"></div>
    </div>
  </body>
</html>

In our example we used center value to center the items in the cross-axis. Try other values and see the result.

The align-content property

The align-content property is used to align a flex container’s lines within the container when there is an extra space in the cross-axis, just as how justify-content aligns individual items within the main axis.

Note: The align-property doesn’t work when there is only one line in the flex container.

align-content

The values for align-content and their meaning are as follows:

  • stretch (default) - lines stretch to take up the available space.
  • flex-start - lines are grouped to the start of the container.
  • flex-end - lines are grouped to the end of the container.
  • center - lines are grouped to the center of the container.
  • space-between - lines are evenly distributed; the first line is at the start of the container while the last one is at the end.
  • space-around - lines are evenly distributed with equal space around each line.

Example of the align-content property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        flex-wrap: wrap;
        align-content: flex-end/* Use another value to see the result */;
        min-height: 250px;
        padding: 10px;
        background-color: #1faadb;
      }
      .flex-container>div {
        width: 45%;
        height: 45px;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
      }
      .flex-container .one,
      .flex-container .nine {
        width: 23%;
      }
      .flex-container .two,
      .flex-container .six {
        width: 9%;
      }
      .flex-container .three {
        width: 25%;
      }
      .flex-container .four {
        width: 35%;
      }
      .flex-container .five,
      .flex-container .eleven {
        width: 32%;
      }
      .flex-container .seven,
      .flex-container .ten {
        width: 6%;
      }
    </style>
  </head>
  <body>
    <p>flex-end</p>
    <div class="flex-container">
      <div class="one"></div>
      <div class="two"></div>
      <div class="three"></div>
      <div class="four"></div>
      <div class="five"></div>
      <div class="six"></div>
      <div class="seven"></div>
      <div class="eight"></div>
      <div class="nine"></div>
      <div class="ten"></div>
      <div class="eleven"></div>
    </div>
  </body>
</html>

The flex-flow property

This is a shorthand property for flex-direction and flex-wrap individual properties, which define together the main and cross axes of the flex container. The default value is row nowrap.

Note: The flex-flow directions are writing mode sensitive, so in rtl (right-to-left) context the content will be reversed respectively.

Example of the flex-flow property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title> 
    <style>
      .flex-container {
        display: flex;
        flex-flow: row-reverse wrap; /* Use another value to see the result */
        padding: 30px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 30%;
        height: 70px;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
        text-align: center;
        font-size: 28px;
        font-weight: 700;
        line-height: 70px;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
    </div>
  </body>
</html>

You can choose another value to see how the position of items changes.

Flex Item Properties

The order property

By default, items are laid out in the order in which they appear in the source code (starting from the lowest numbered ordinal group and going up). To change the order of items in the flex container the order property is used.

The order property sets the order of flex items by assigning them to ordinal groups. It takes a single integer value, which defines the ordinal group the flex item belongs to. Default value is 0.

flex-order

Example of the order property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        flex-flow: row wrap;
        padding: 30px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 30%;
        height: 70px;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
        text-align: center;
        font-size: 28px;
        font-weight: 700;
        line-height: 70px;
        color: #fff;
      }
      .item-one { 
        order: 1;
      }
      .item-four {
        order: -1;
      }
      .item-five { 
        order: 0;
      }
      .item-three { 
        order: 2;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div class="item-one">1</div>
      <div class="item-two">2</div>
      <div class="item-three">3</div>
      <div class="item-four">4</div>
      <div class="item-five">5</div>
    </div>
  </body>
</html>

The align-self property

The property is used for individually aligning items within the flex container. Flex items are aligned in the cross axis of the flex container’s line (just as justify-content, but in the perpendicular direction). When set the align-self property overrides the alignment specified by align-items.

Note: If any of the item's cross-axis margin is set to auto, then align-self is ignored.

The align-self property has the same values as the align-items. They are listed below for your convenience.

  • stretch (default) - items are stretched to fill the container.
  • flex-start - items are stacked to the cross start of the container.
  • flex-end- items are stacked to the cross end of the container.
  • center - items are stacked at the center of the cross axis.
  • baseline - items are aligned such as their baselines are aligned.

align-self

Example of the align-self property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        justify-content: space-between;
        height: 300px;
        padding: 10px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 15%;
        height: 80%;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
      }
      div.item-two {
        width: 20%; 
      }
      div.item-three {
        align-self: flex-end;
        height: 80px; 
        margin: 0 10%;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div class="item-one"></div>
      <div class="item-two"></div>
      <div class="item-three"></div>
      <div class="item-four"></div>
    </div>
  </body>
</html>

The flex-grow property

The flex-grow property defines the ability of an item to grow if necessary. It sets the flex grow factor (relatively to the rest of the items within a container), which specifies the space that the item should take up in the container when distributing positive space.

The property takes a unitless value that serves as a proportion.

flex-grow

Note: Value cannot be a negative number.

If all items in the container have the same value for flex-grow (for example, 1) than all items have the same size in the container.

flex-grow-same

If the size of one of the flex items is different (for example, 2), then this item will take up twice more space relative to the size of the other items (the size of which is set to 1).

flex-grow-different

Example of the flex-grow property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        margin-bottom: 20px;
      }
      .flex-container div {
        flex-grow: 0.2;
        padding: 30px 5px;
        margin-right: -2px;
        border: 2px solid #8ebf42;
      }
      .flex-container div.two {
        flex-grow: 5;
      }
      .flex-container span {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 60px;
        height: 60px;
        margin: auto;
        border-radius: 50%;
        background-color: #8ebf42;
        font-size: 28px;
        font-weight: 700;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div>
        <span>1</span>
      </div>
      <div>
        <span>2</span>
      </div>
      <div>
        <span>3</span>
      </div>
      <div>
        <span>4</span>
      </div>
      <div><span>5</span>
      </div>
    </div>
    <div class="flex-container">
      <div>
        <span>1</span>
      </div>
      <div class="two">
        <span>2</span>
      </div>
      <div>
        <span>3</span>
      </div>
      <div>
        <span>4</span>
      </div>
      <div>
        <span>5</span>
      </div>
    </div>
  </body>
</html>
We recommend using flex shorthand property instead of flex-grow to control flexibility, as it correctly resets any unspecified components to accommodate common uses.

The flex-shrink property

The flex-shrink is set to allow a flex item to shrink. It specifies the space that the item should take up in the container when negative space is distributed.

The property takes a unitless value.

Note: Value cannot be a negative number.

By default all flex items can be shrunk, but if we set value to 0 (don't shrink) they will preserve the original size.

flex-shrink

Example of the flex-shrink property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
      }
      .flex-container div {
        width: 120px;
        padding: 30px 10px;
        margin-right: -2px;
        border: 2px solid #8ebf42;
      }
      .flex-container div.two {
        flex-shrink: 0;
      }
      .flex-container span {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 60px;
        height: 60px;
        margin: auto;
        border-radius: 50%;
        background-color: #8ebf42;
        font-size: 28px;
        font-weight: 700;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div>
        <span>1</span>
      </div>
      <div class="two">
        <span>2</span>
      </div>
      <div>
        <span>3</span>
      </div>
      <div>
        <span>4</span>
      </div>
      <div>
        <span>5</span>
      </div>
      <div>
        <span>6</span>
      </div>
    </div>
  </body>
</html>
We recommend using flex shorthand property instead of flex-shrink to control flexibility, as it correctly resets any unspecified components to accommodate common uses.

The flex-basis property

The flex-basis property sets the initial size of a flex item, before remaining space is distributed according to the flex factors. The property is specified by the keyword content or width.

The flex-basis values are as follows:

  • auto (default) -the length is equal to the length of the flexible item.
  • width - an absolute length, or a percentage of the parent flex container's main size property, or the keyword auto. Negative values are invalid.
  • content - determines automatic sizing, based on the flex item’s content.
  • initial - sets this property to its default value.
Note: The content property isn't well supported yet, so it's not easy to understand what its brethren max-content, min-content, and fit-content do.

flex-basis

Example of the flex-basis property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        background-color: #8ebf42;
      }
      .flex-container div {
        padding: 30px 10px;
        margin-right: -2px;
        border: 2px solid #8ebf42;
        background-color: #fff;
      }
      .flex-container div.four {
        flex-basis: 25%;
      }
      .flex-container span {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 60px;
        height: 60px;
        margin: auto;
        border-radius: 50%;
        background-color: #8ebf42;
        font-size: 28px;
        font-weight: 700;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div>
        <span>1</span>
      </div>
      <div>
        <span>2</span>
      </div>
      <div>
        <span>3</span>
      </div>
      <div class="four">
        <span>4</span>
      </div>
      <div>
        <span>5</span>
      </div>
    </div>
  </body>
</html>

The flex property

The flex property is the shorthand for flex-grow,flex-shrink and flex-basis together. The flex-shrink and flex-basis are optional.

Among other values this property can accept auto (1 1 auto) or none (0 0 auto).

We strongly recommend using flex shorthand property instead of individual properties.

Example of the flex property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        height: 150px;
        padding: 10px;
        margin-bottom: 20px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 15%;
        margin: 5px;
        border-radius: 3px;
        background-color: #8ebf42;
      }
      .second > div {
        flex: 1;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <div class="flex-container second">
      <div></div>
      <div></div>
      <div></div>
    </div> 
  </body>
</html>
Note: CSS float, clear and vertical-align properties have no effect on flex items.

Flexbox Examples

Let’s have a look at some CSS flexbox examples and see what kind of layouts you can use for your own web projects.

Centering Elements Vertically and Horizontally

Centering elements by all available means in CSS has always been a problem. With the advent of Flexbox this problem is easily solved. With align-items, align-self and justify-content properties you can align elements both vertically or horizontally.

Example of the align-items, align-self and justify-content properties for centering elements vertically and horizontally:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .flex-container {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 200px;
        border: 1px dashed #666;
      }
      .flex-container > div {
        width: 70px;
        height: 70px;
        margin: 5px;
        border-radius: 3px;
        background-color: #1faadb;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </body>
</html>

Using Flexbox you can create a navigation bar with menu items aligned to the left, and the search bar aligned to the right (or vice versa). The navigation bar is responsive, it expands or collapses depending on the screen size.

Example of the responsive navigation bar:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .main-nav {
        display: flex;
        padding: 15px;
        border-radius: 5px;
        background: #1c87c9;
        color: #fff;
        font-weight: 500;
      }
      .main-nav > ul {
        display: flex;
        flex: 2;
        padding: 0;
        margin: 0;
        list-style-type: none;
      }
      .main-nav li {
        margin-right: 20px;
      }
      .main-nav > form {
        display: flex;
        justify-content: flex-end;
        flex: 1;
      }
      .main-nav input {
        flex: 1;
        padding: 5px;
      }
      .main-nav button {
        padding: 0 20px;
        margin-left: 10px;
        border: 0;
        border-radius: 20px;
        background: #fff;
        color: #666;
      }
      @media screen and (max-width: 575px) {
        .main-nav {
          flex-direction: column;
        }
        .main-nav ul {
          margin-bottom: 10px;
        }
      }
    </style>
  </head>
  <body>
    <nav class="main-nav">
      <ul>
        <li>Home</li>
        <li>About us</li>
        <li>Services</li>
        <li>Contact us</li>
      </ul>
      <form>
        <input type="search" placeholder="Search">
        <button type="button">Go</button>
      </form>
    </nav>
  </body>
</html>

The Holy Grail Layout

The Holy Grail layout pattern is very popular on the web. It includes header, footer, the main content area with fixed-width navigation on the left, content in the middle and a fixed-width sidebar on the right.

Example of the holy grail layout:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      * {
        box-sizing: border-box;
        font-size: 18px;
      }
      body {
        display: flex;
        flex-direction: column;
        min-height: 100vh;
        margin: 0;
      }
      .main {
        display: flex;
        flex: 1;
      }
      .main > article {
        flex: 1;
      }
      .main > nav,
      .main > aside {
        flex: 0 0 20vw;
        background: #d5dce8;
      }
      .main > nav {
        order: -1;
      }
      header,
      footer {
        background: #1c87c9;
        height: 15vh;
      }
      header,
      footer,
      article,
      nav,
      aside {
        padding: 20px;
      }
    </style>
  </head>
  <body>
    <header>Header</header>
    <div class="main">
      <article>Article</article>
      <nav>Nav</nav>
      <aside>Aside</aside>
    </div>
    <footer>Footer</footer>
  </body>
</html>

Practice Your Knowledge

Which of the following are properties of Flexbox in CSS?

Quiz Time: Test Your Skills!

Ready to challenge what you've learned? Dive into our interactive quizzes for a deeper understanding and a fun way to reinforce your knowledge.