Backgorund

The Flexbox Layout module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.

The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space. A flex container expands items to fill available free space, or shrinks them to prevent overflow.

Basic and Terminology

terminologydescription
main axisThe main axis of a flex container is the primary axis along which flex items are laid out.
main-start, main-endThe flex items are placed within the container starting from main-start and going to main-end.
main-sizeA flex item’s width or height, whichever is in the main dimension, is the item’s main size.
cross-sizeThe axis perpendicular to the main axis is called the cross axis.
cross-start, cross-endFlex 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 sizeThe width or height of a flex item, whichever is in the cross dimension, is the item’s cross size.

Properties for the parent

display

This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children.

.container {
  display: flex; /* or inline-flex */
}

flex-direction

This establishes the main-axis, thus defining the direction flex items are placed in the flex container.

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

flex-wrap

By default, flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property.

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

more: Wrap Your Brain Around Flex-Wrap

flex-flow

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

flex-flow: <‘flex-direction> || <‘flex-wrap>

justify-content

This defines the alignment along the main axis.

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}

align-items

This defines the default behavior for how flex items are laid out along the cross axis on the current line.

.container {
  align-items: stretch | flex-start | flex-end | center | baseline;
}

align-content

This aligns a flex container’s lines within when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.

This property has no effect when there is only one line of flex items.

Once your flex items wrap to a new line, you need to learn how to control the positioning of those lines. This is what align-content is all about.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

Properties for the children

order

By default, flex items are laid out in the source order. However, the order property controls the order in which they appear in the flex container.

.item {
  order: <integer>; /* default is 0 */
}

flex-grow

This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.

If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others.

.item {
  flex-grow: <number>; /* default 0 */
}

flex-shrink

This defines the ability for a flex item to shrink if necessary.

.item {
  flex-shrink: <number>; /* default 1 */
}

eg.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        .container {
            width: 300px;
            height: 500px;
            display: flex;
        }
        .item {
            height: 120px;
            flex-basis: 106px;
            flex-grow: 1;
        }
        .item.first {
            background-color: red;
            flex-shrink: 2;
        }
        .item.second {
            background: blue;
            flex-shrink: 3;
        }
        .item.third {
            background-color:green;
            flex-shrink: 1;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item first"></div><!-- width: 100px -->
        <div class="item second"></div><!-- width: 97px -->
        <div class="item third"></div><!-- width: 103px -->
    </div>
</body>
</html>

flex-basis

This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword.

  1. The auto keyword means “look at my width or height property”

  2. The content keyword means “size it based on the item’s content”

    If no flex-basis is specified, then the flex-basis falls back to the item’s width property.

    If no width is specified, then the flex-basis falls back to the computed width of the item’s contents.

    Flex-basis value is limited by both the min-width and max-width of the item.

A best practice is to just use flex-basis instead of width or height.

.item {
  flex-basis: <length> | auto; /* default auto */
}

more: The Difference Between Width and Flex Basis

flex

This is the shorthand for flex-grow, flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) are optional. Default is 0 1 auto.

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

align-self

This allows the default alignment to be overridden for individual flex items.

Note that float, clear and vertical-align have no effect on a flex item.
.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}