CSS Reference Concept

Flexbox

Flexbox, or the Flexible Box Layout, is a new layout mode in CSS3 designed for laying out complex applications and web pages.

In CSS 2.1, four layout modes were defined which determine the size and position of boxes based on their relationships with their sibling and ancestor boxes: the block layout designed for laying out documents, and that lays elements on a page vertically; the inline layout designed for laying out text horizontally inside block-level containers; the table layout designed for laying out two-dimensional data in a tabular format; and the positioned layout designed for very explicit positioning without much regard for other elements in the document.

Flexbox is similar to the block layout, except that it lacks many of the properties that can be used in a block layout, such as floats and columns. But then again it has more flexibility for distributing space and aligning content in ways that web applications and complex web pages often need. It solves many other layout problems that we have been fighting against and trying to solve for a very long time—such as vertical centering, for example, among many others.

Flexbox allows you to lay out elements in a container, arrange and (re)order them, align them, and distribute the space between (and/or around) them, regardless of their size. It allows you to make them literally flexible—items inside a container can be stretched and shrunk to accommodate the available space, and can be sized in proportionally to each other, and any available space between or around them can be distributed among them based on a proportion that you get to specify.

Using flexbox, you can also lay elements out inside a container in either directions: horizontal or vertical, called the flex directions; you’re not bound to just one direction as in other layout modes. This allows for the creation of more adaptive and responsive layouts that adapt to the layout changes on different screen sizes and orientations.

Last but not least, you can change the visual order of elements inside the container without affecting their actual order in the markup. This means that you can change the order in which certain items appear on the page, while preserving their order in the markup. This is useful for when you want to highlight certain items, such as a featured blog post, even if those items don’t come first in the markup.

Summary of Flexbox Properties

  • <a href="#section_flex-direction">flex-direction</a>
  • <a href="#section_flex-wrap">flex-wrap</a>
  • <a href="#section_flex-flow">flex-flow</a>
  • <a href="#section_justify-content">justify-content</a>
  • <a href="#section_align-items">align-items</a>
  • <a href="#section_align-content">align-content</a>
  • <a href="#section_order">order</a>
  • <a href="#section_align-self">align-self</a>
  • <a href="#section_flex-grow">flex-grow</a>
  • <a href="#section_flex-shrink">flex-shrink</a>
  • <a href="#section_flex-basis">flex-basis</a>
  • <a href="#section_flex">flex</a>

Creating a Flexible Layout: The Flex Container and Items

The first step to start using Flexbox is to create a flex container. Children of a flex container are called the flex items, and are laid out inside the flex container using the Flexbox properties. Some of the Flexbox properties apply to the container, others are applied to the flex items.

A flex container is created by setting the display property of an element to either flex or inline-flex.

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

display: flex creates a block-level flex container; display: inline-flex creates an inline-level flex container. The flex container becomes a flex context for its direct descendants.

Children of a flex container, the flex items, are laid out using the Flexbox layout. Any element outside a flex container is not affected by the Flexbox layout defined on it, and will be rendered as it normally would in the page.

Concepts and Terminology

Before going through the Flexbox properties that control and customize Flexbox layout, there are two concepts and terms that you should get familiar with first: flex axes and flex lines.

Flex Axes

Unlike block and inline layout, whose layout is based on block and inline flow directions, flex layout is based on flex directions.

The concept of flex directions is based on the concept of axes that determine the directions along which flex items are laid. The following illustration shows the axes defined on a flex container:

flex-axes

Depending on the values of the Flexbox properties, flex items will be laid out inside a flex container following either the main axis or the cross axis.

  • The main axis of a flex container is the primary axis along which flex items are laid out. It extends in the main dimension.
  • The flex items are placed within the container starting on the main-start side and going toward the main-end side.
  • 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.
  • The axis perpendicular to the main axis is called the cross axis. It extends in the cross dimension.
  • 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.
  • Flex lines (see next section below) 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.

It is necessary that you familiarize yourself with these concepts before starting to use the Flexbox layout. Everything in the Flexbox layout is relative to these two axes.

Flex Lines

Flex items in a flex container are laid out and aligned within flex lines, a hypothetical line used for grouping and alignment of flex items inside their container. Flex lines follow the main axis. A flex container can be either single-line or multi-line, depending on the flex-wrap property:

  • A single-line flex container lays out all of its children in a single line, even if that would cause its contents to overflow.
  • A multi-line flex container breaks its flex items across multiple lines, similar to how text is broken onto a new line when it gets too wide to fit on the existing line. When additional lines are created, they are stacked in the flex container along the cross axis according to the flex-wrap property. Every line contains at least one flex item, unless the flex container itself is completely empty.

Writing Modes

The above illustration assumes that the writing mode is a left-to-right (LTR) mode. The flex line follows the direction of the text which, in a left-to-right mode, is left to right, top to bottom.

However, if you change the direction of the text using the direction property, the direction of the flex line will also change, changing the direction the flex items are laid out along.

Also, if the writing mode changes, the directions of both the main axis and cross axis will also change. For example, in a Japanese language layout, the main axis is vertical and the cross axis is horizontal. See the flex-flow property section for an example.

For more information about the possible writing modes and directions, see the CSS Writing Modes Module and the direction property entry.

Flexbox Properties: Flex Container Properties

The flex-direction Property

flex-direction: row | row-reverse | column | column-reverse
                

flex-direction-illustration

The flex-direction property specifies how flex items are placed in the flex container, by setting the direction of the flex container’s main axis. This determines the direction that flex items are laid out in. The direction of the axes is affected by the writing mode and directionality of the text (continue reading).

The possible values have the following meanings:

row
This is the initial value. The flex container’s main axis has the same orientation as the current writing mode. The main-start is on the left in a left-to-right language, and the main-end is on the right. In a right-to-left language, the main-start is on the right and the main-end is on the left.
row-reverse
Same as row, except the main-start and main-end directions are swapped. The flex container’s main axis has the opposite orientation as the current writing mode.
column
The flex container’s main axis is rotated so that the main-start is at the top and the main-end is at the bottom. Basically, flex items are laid vertically from top to bottom in a horizontal language. If the language is vertical, then the column value will be horizontal with respect to the language.
column-reverse
Same as column, except that main-start and main-end directions are swapped.

Note that the reverse values do not reverse box ordering; like writing-mode and direction, they only change the direction of flow. Painting order, speech order, and sequential navigation orders are not affected.

The following demo illustrates the result of applying the four flex-direction values to a flex container.

View this demo on the Codrops Playground

The following is the same demo with a different writing mode. The directionality of the text is set to rtl (right-to-left). See how that affects the direction of the main axis and hence the direction that the items are laid out in.

View this demo on the Codrops Playground

It is worth noting at this point that a flex container has initially one flex line, and the flex items are laid on that single line, even if it means that they will overflow the container. In order to have the items wrap and span across multiple lines, the flex-wrap property is used (see next section).

The flex-wrap Property

flex-wrap: nowrap | wrap | wrap-reverse
                

flex-wrap-illustration

The flex-wrap property controls whether the flex container is single-line or multi-line, and the direction of the cross-axis, which determines the direction new lines are stacked in.

The possible values have the following meanings:

nowrap
This is the initial value. The flex container is single-line, and all items are laid out on that line, even if it means they might overflow the container. The direction of the flex line depends on the directionality of the text (see flex-direction above).
wrap
The flex items will wrap onto additional flex lines if there isn’t enough room for them on the first flex line. Additional flex lines are added in the direction of the cross axis, which is affected by the directionality of the text (see flex-direction above).
wrap-reverse
Same as wrap, except the cross-start and cross-end directions are swapped. This means that additional flex lines are added in the opposite direction of the cross axis.

The following demo illustrates the result of applying the four flex-wrap values to a flex container. Note that the other Flexbox properties are all set to their default values.

View this demo on the Codrops Playground

The flex items will all try to fit on one line, as you can see in the demo. Using different flex-wrap values, you can change that and have them wrap across multiple lines.

The flex-flow Property

flex-flow: <'flex-direction'> <'flex-wrap'>
                

The flex-flow property is a shorthand for setting the flex-direction and flex-wrap properties, which together define the flex container’s main and cross axes.

The initial value of the flex-flow property is the concatenation of the initial values of the flex-direction and flex-wrap properties:

flex-flow: row nowrap;
                

The following examples show the result of applying different flex-flow values to a flex container. The examples show the result of applying the row and column values of the flex-direction property with the different values from the flex-wrap property. Try changing the values of the flex-flow property to include the row-reverse and column-reverse values of the flex-direction property to see how it changes the layout.

View this demo on the Codrops Playground

Note that the flex-flow directions are writing mode sensitive. In vertical Japanese, for example, a row flex container lays out its contents from top to bottom, as seen in this example:

flex-flow-example
Image showing the difference in layout directions between a horizontal language (English) and a vertical language (Japanese). (Source)

The justify-content Property

justify-content: flex-start | flex-end | center | space-between | space-around
                

justify-content-illustration

The justify-content property aligns flex items along the main axis of the current line of the flex container. This is done after any flexible lengths and any auto margins have been resolved. Typically it helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.

The possible values have the following meanings:

flex-start
This is the initial value. Flex items are packed toward the start of the line.
flex-end
Flex items are packed toward the end of the line.
center
Flex items are packed toward the center of the line, with equal amounts of empty space between the main-start edge of the line and the first item on the line and between the main-end edge of the line and the last item on the line. (If the leftover free-space is negative, the flex items will overflow equally in both directions.)
space-between
Flex items are evenly distributed in the line. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to flex-start. Otherwise, the first flex item on the line is placed on the main-start edge of the line, the last flex item on the line is on the main-end edge of the line, and the remaining flex items on the line are distributed so that the spacing between any two adjacent items is the same.
space-around
Flex items are evenly distributed in the line, with half-size spaces on either end. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to center. Otherwise, the flex items on the line are distributed such that the spacing between any two adjacent flex items on the line is the same, and the spacing between the first/last flex items and the flex container edges is half the size of the spacing between flex items.

The following demo shows the result of applying the different justify-content values to a flex container. Other Flexbox properties are set to their default values.

View this demo on the Codrops Playground

The align-items Property

align-items: flex-start | flex-end | center | baseline | stretch
                

align-items-illustration

The align-items property is similar to the justify-content property, but instead of aligning flex items in the main axis, align-items is used to align flex items in the cross-axis (perpendicular to the main axis).

The possible values have the following meanings:

flex-start
Flex items are packed toward the cross-start of the line.
flex-end
Flex items are packed toward the cross-end of the line.
center
Flex items are packed toward the center of the line, with equal amounts of empty space between the cross-start edge of the line and the first item on the line and between the cross-end edge of the line and the last item on the line. (If the leftover free-space is negative, the flex items will overflow equally in both directions.)
baseline
Flex items are aligned such that their baselines align. The item with the largest distance between its cross-start margin edge and its baseline is flushed with the cross-start edge of the line.
stretch
This is the initial value. The flex items are stretched out from the cross-start to the cross-end, while still respecting the constraints imposed by min-height/min-width/max-height/max-width. Note that if the flex container’s height is constrained this value may cause the contents of the flex items to overflow the items.

The following demo shows the result of applying the different align-items values to a flex container. Other Flexbox properties are set to their default values.

When the value of align-items is baseline, notice how the baseline of the numbers in the flex items is aligned (a pink line appears).

View this demo on the Codrops Playground

Note that the align-self property allows the alignment specified by align-items to be overridden for individual flex items.

The align-content Property

align-content: flex-start | flex-end | center | space-between | space-around | stretch
                

align-content-illustration

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. This property has no effect when the flex container has only a single line.

The possible values have the following meanings:

flex-start
Lines are packed toward the cross-start of the flex container.
flex-end
Lines are packed toward the cross-end of the flex container.
center
Lines are packed toward the center of the flex container, with equal amounts of empty space between the cross-start edge of the container and the first line in the container and between the cross-end edge of the container and the last line in the container. (If the leftover free-space is negative, the lines will overflow equally in both directions.)
space-between
Lines are evenly distributed in the flex container. If the leftover free-space is negative this value is identical to flex-start. Otherwise, the cross-start edge of the first line in the flex container is placed on the cross-start content edge of the flex container, the cross-end edge of the last line in the flex container is placed on the cross-end content edge of the flex container, and the remaining lines in the flex container are distributed so that the spacing between any two adjacent lines is the same.
space-around
Lines are evenly distributed in the flex container, with half-size spaces on either end. If the leftover free-space is negative this value is identical to center. Otherwise, the lines in the flex container are distributed such that the spacing between any two adjacent lines is the same, and the spacing between the first/last lines and the flex container edges is half the size of the spacing between flex lines.
stretch
This is the initial value. Lines stretch to take up the remaining space. If the leftover free-space is negative, this value is identical to flex-start. Otherwise, the free-space is split equally between all of the lines, increasing their cross size.

Note that only flex containers with multiple lines ever have free space in the cross-axis for lines to be aligned in, because in a flex container with a single line the sole line automatically stretches to fill the space (that’s the default behavior).

The following demo shows the result of applying the different align-content values to a flex container. All Flexbox properties are set to their default values, except that the flex-wrap property is set to wrap to make sure the items are spread across multiple lines, because, as mentioned above, the align-content property only works on a flex container that is multi-line.

View this demo on the Codrops Playground

Flexbox Properties: Flex Items Properties

The order Property

order: <integer>
                

order-illustration

Flex items are, by default, displayed and laid out in the same order as they appear in the source document. The order property can be used to change this ordering.

The order property controls the order in which flex items appear within their flex container, by assigning them to ordinal groups. It takes a single <integer> value, which specifies which ordinal group the flex item belongs to.

Then, a flex container lays out its content in order-modified document order, starting from the lowest numbered ordinal group and going up. Items with the same ordinal group are laid out in the order they appear in the source document.

The initial order of all flex items is zero (0) and the flex items are rendered in the order they appear in the source code. The order property can also take negative values.

Note that the order in which the flex item appears inside its container changes only on screen, not in the source document. This means that screen readers will read the flex items in the order they appear in the document source, not the order specified using the order property. The default traversal order of sequential navigation modes (such as cycling through links, for example using nav-index or tabindex) is also not affected (except in Firefox, which changes the order of traversal of links based on the visual order). Hence, you should use the order property only for visual, not logical, reordering of content.

This property could be useful for reordering blog posts, for example, where you may want to feature a blog post at the beginning of the page, even if that article is no longer the latest. The logical order that is accessible for screen readers will be maintained, and the article can be visually replaced without affecting the accessibility.

Try changing the order of the items in the following flex container to see how they are reordered visually.

View this demo on the Codrops Playground

The align-self Property

align-self: auto | flex-start | flex-end | center | baseline | stretch
                

align-self-illustration

Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. align-items sets the default alignment for all of the flex container’s items. The align-self property allows this default alignment to be overridden for individual flex items. In order to fully understand the values and concepts behind this property, please see the align-items property description.

The possible values have the following meanings:

auto
This is the initial value. A value of auto computes to the value of align-items on the element’s container, or stretch if the element has no parent. In other words, the item will be aligned based on the default value or the value specified for the align-items property.
flex-start
The flex item is packed toward the cross-start of the line.
flex-end
The flex item is packed toward the cross-end of the line.
center
The flex item’s margin box is centered in the cross axis within the line. (If the cross size of the flex line is less than that of the flex item, it will overflow equally in both directions.)
baseline
If the flex item’s inline axis is the same as the cross axis, this value is identical to flex-start. Otherwise, it participates in baseline alignment: all participating flex items on the line are aligned such that their baselines align, and the item with the largest distance between its baseline and its cross-start margin edge is placed flush against the cross-start edge of the line.
stretch
The flex item is stretched out from the cross-start to the cross-end, while still respecting the constraints imposed by min-height/min-width/max-height/max-width. Note that if the flex container’s height is constrained this value may cause the contents of the flex item to overflow the item.

In the following demo, the items are aligned inside the flex container first using the align-items property with a value of center. Any value applied to the third item (with the number three) using align-self will override that applied using align-items. Change the value of the align-self property to see how the item’s alignment is affected.

View this demo on the Codrops Playground

The flex-grow Property

flex-grow: <number>
                

flex-grow-illustration

The flex-grow property sets the flex grow factor of a flex item. A flex grow factor is a <number> which determines how much the flex item will grow relative to the rest of the flex items in the flex container when positive free space is distributed. The initial value is zero (0), and negative numbers are invalid.

If the flex items are laid out on the flex line such that they don’t take up the entire space on that line, you can “expand” the flex items so that they fill up the entire line. The amount of available space on the line can be distributed among the flex items following a specific proportion that you can specify using the flex-grow property. The higher the flex-grow value, the more the item will be allowed to grow relative to the other items.

For example, you can distribute the space among the flex items such that one of these items always gets twice as much space as the others. You can do that by setting the flex-grow property value to 2 (two). An item with flex-grow: 2 will grow twice as much as an item with flex-grow: 1—it gets twice as much space as the latter. So, for every one pixel that the second item gets, the first item grows by two pixels.

Try entering different values for the flex-grow property in the following demo to see how the elements grow.

View this demo on the Codrops Playground

Note that the flex-grow property is animatable, except between the value zero (0) and other values.

The flex-grow property is usually used in conjunction with the flex-shrink and flex-basis properties, in the shorthand flex property.

The flex-shrink Property

flex-shrink: <number>
                

The flex-shrink property sets the flex shrink factor of a flex item. A flex shrink factor is a <number> which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed. The flex shrink factor is multiplied by the flex basis (see flex-basis) when distributing negative space. The initial value is zero (1), meaning that the items don’t shrink by default, and negative numbers are invalid.

If the sum of the main sizes (see concepts and terminology) of all flex items is greater than the main size of the flex container, you can specify just by how much you want to “shrink” the flex items. The amount by which the flex items’ main sizes exceed the container’s main size is the negative space. Using the flex-shrink property, you can distribute this negative space over the flex items. The negative space is distributed in proportion to flex-basis multiplied by the flex-shrink ratio, where the flex basis is the initial main size of the flex item, before free space is distributed according to the flex factors.

For example, you can distribute the space among the flex items such that one of these items always gets twice as much negative space as the others. You can do that by setting the flex-shrink property value to 2 (two). An item with flex-shrink: 2 will shrink twice as much as an item with flex-shrink: 1—it gets twice as much negative space as the latter. So, for every one pixel that the second item shrinks, the first item shrinks by two pixels. The higher the flex-shrink value, the more the item will shrink relative to the other items.

The items in the following demo are laid inside a container that has a main size of 500px. Each of the four items has a main size basis (or a flex basis) of 200px. The items (combined) obviously have a larger main size than the container’s. Because this is a Flexbox layout, the items will automatically shrink to fit inside their container. However, using the flex-shrink property, you can control the ratio by which the items are to be shrunk. Try entering different values for the flex-shrink property in the following demo to see how the elements shrink.

View this demo on the Codrops Playground

Note that the flex-shrink property is animatable, except between the value zero (0) and other values.

The flex-shrink property is usually used in conjunction with the flex-basis and flex-grow properties, in the shorthand flex property.

The flex-basis Property

flex-basis: auto | <'width'>
                

The flex-basis property takes the same values as the width property, and sets the flex basis: the initial main size (see concepts and terminology) of the flex item, before free space is distributed according to the flex factors (see flex-shrink and flex-grow).

Except for auto, flex-basis is resolved the same way as width in horizontal writing modes: percentage values for the flex-basis property are set relative to the flex container’s inner main size. Also, flex-basis determines the size of the element’s content box, unless otherwise specified using the box-sizing property.

If the specified flex-basis is auto, the used flex basis is the value of the flex item’s main size property. (This can itself be the keyword auto, which sizes the flex item based on its contents.)

The flex-basis property is usually used in conjunction with the flex-shrink and flex-grow properties, in the shorthand flex property.

In the following demo, the flex-basis is used in the flex shorthand. The flex-shrink and flex-grow properties are set so that the items neither grow nor shrink. The value specified using flex-basis defines the main size of each item. Try changing the values of all three properties in the flex shorthand to see how the width of the items responds. For example, try using a different flex-grow value to see how the size of an item changes after positive space is distributed.

View this demo on the Codrops Playground

The flex Property

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
                

The flex property is a shorthand property for setting the flex-grow, flex-shrink, and flex-basis properties.

When an element is a flex item, flex is used instead of the main size property (width or height properties, see concepts and terminology) to determine the main size of the element. If an element is not a flex item, flex has no effect.

The initial value is 0 1 auto. The flex-grow and flex-shrink properties are optional and can be omitted from the flex declaration.

When the flex-grow value is omitted, it is set to 1. Note that 1 is not the initial value of the flex-grow property! It is only the value used when flex-grow is omitted from the shorthand declaration.

When the flex-shrink property is omitted, it is set to 1. Note that the flex shrink factor is multiplied by the flex basis when distributing negative space. (See flex-shrink)

When the flex-basis value is omitted, it is set to 0%.

The initial values of flex-grow and flex-shrink properties are different from their defaults when omitted in the flex shorthand. This so that the flex shorthand can better accommodate the most common cases.

The following are some of the common flex values and their meanings:

flex: 0 auto / flex: initial
This is equivalent to flex: 0 1 auto, which is the initial value. This value sizes the item based on the width/height properties. (If the item’s main size property computes to auto, this will size the flex item based on its contents.) Makes the flex item inflexible when there is positive free space, but allows it to shrink to its min-size when there is insufficient space.
flex: auto
This is equivalent to flex: 1 1 auto. This value sizes the item based on the width/height properties, but makes them fully flexible, so that they absorb any free space along the main axis. If all items are either flex: auto, flex: initial, or flex: none, any positive free space after the items have been sized will be distributed evenly to the items with flex: auto.
flex: none
This is equivalent to flex: 0 0 auto. This value sizes the item according to the width/height properties, but makes the flex item fully inflexible. This is similar to initial, except that flex items are not allowed to shrink, even in overflow situations.
flex: <positive-number>
This value is equivalent to flex: <positive-number> 1 0%. This value makes the flex item flexible and sets the flex basis to zero, resulting in an item that receives the specified proportion of the free space in the flex container. If all items in the flex container use this pattern, their sizes will be proportional to the specified flex factor.

Note that, by default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property.

Change the value of the flex property in the following demo to see how it affects the flex items. You can also use a different flex value for every item. The demo is set so that the items have a flex basis of 100px, and neither shrink nor grow. Play with the values to your liking to get a better understanding of how the property works with different values.

View this demo on the Codrops Playground

Examples

Flexbox provides us with simple solutions for some of the oldest problems and “holy grails” in web design.

Vertical and Horizontal Centering

Vertical centering has been one of the most sought after CSS solutions for a very long time. With Flexbox, centering an element inside its container becomes as easy as pie. You start by creating a flex container:

.container {
    display: flex;
}
                

Then, using the justify-content property, you center the element across the main axis (horizontally), and using the align-items property, you center the element vertically.

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

And that’s it! No matter the size of the element, it will always be centered inside its container. The following is a live demo of the above code sample.

View this demo on the Codrops Playground

Equal-Height Multi-Column “Holy Grail” Layout

One of many things we usually try to accomplish for our designs but have no straightforward way in CSS to do so, is to create a multi-column (say two-column or three-column) layout where all the columns have the same height no matter how much content each contains. This is typical in two-column blog layouts or multi-column magazine layouts.

Using flexbox, creating equal-height columns is as easy as 1 2 3.

We’ll be using a very simple markup for a simple blog.

<header><!-- header stuff --></header>
<div class="container">
    <section class="main"></section>
    <aside class="sidebar"></aside>
</div>
<footer><!-- footer stuff --></footer>
                

We want to make sure the sidebar has the same height as the main section, no matter the amount of content in each of them. Previously, we used to use hack our way to this using techniques like faux columns, among others. Using Flexbox, we can achieve equal heights like so:

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

Then, you can set the widths and flex grow/shrink factors using the flex property to whatever values you want. The following is a live demo showing the equal-height columns in action. The width of the two columns is set using the flex-basis property as part of the flex shorthand, along with the flex grow factor.

View this demo on the Codrops Playground

Using media queries, you can change the layout of the two columns and have them stack on top of each other on smaller screens, using the flex-direction property.

@media screen and (max-width:500px) {
    .container {
        flex-direction: column;

    }
}
                

As mentioned before, you can reorder the way the items appear, too, using the order property. So, if you have three columns, for example, and one of these columns contains ads, and you want these ads to appear on top or at the bottom on small screens, or even somewhere in between, you can control the order of appearance once the columns are stacked on top of each other on smaller screens.

Sticky Footer

Having the footer stick to the bottom of the page even if the content of the page above the footer is smaller than the viewport is something that almost every one of us has had to do at some point. There have been several techniques around the web for some time that allow you to do that, but all of them rely on knowing the height of the footer; without knowing the height of the footer, those techniques wouldn’t work.

Flexbox allows us to stick the footer to the bottom of the page (not fixing it, though) easily. You start by laying the flex items vertically using flex-direction. Then, you have the main content section expand/grow using flex-grow, thus pushing the footer down to the bottom of the page. However, the page would need to have a height that’s equal to the height of the viewport, or more.

<body>
    <header><!-- header stuff --></header>
    <section class="content"><!-- main content --></section>
    <footer><!-- footer stuff --></footer>
</body>
                

The CSS is simple:

body {
    display: flex;
    /* make sure it's at least as tall as the viewport */
    min-height: 100vh;
    /* lay items out vertically */
    flex-direction: column;
}
section.content {
    flex-grow: 1;
}
                

The following is a live demo showing the above code in action:

View this demo on the Codrops Playground

Flexible Navigation

Another way Flexbox helps is with laying out navigation items. Before flexbox, we could lay the items out using either inline, inline-block, or block displays, or by floating the elements next to each other. So, if the navigation takes up the entire horizontal space, and the items aren’t wide enough (text-wise) to fill up that space, they will be flushed either to the right or to the left, with lots of space on the other side. If you were to spread them to fill the space, you would have to set up specified widths, and do the calculations necessary for that, and then add padding and possible margins to space the items out.

As you have guessed, Flexbox makes distributing the navigation item a lot simpler. Using justify-content, you can spread the items with space between them.

ul.navigation {
    width: 100%;
    display: flex;
    justify-content: space-between;
}
                

Moreover, you can turn it into a vertical navigation with the items stacked on top of each other on small screens also quite as simply.

@media screen and (max-width: 430px) {
    .navigation {
        flex-direction: column;
        /* other general styles if needed */
    }
}
                

The following is a live demo of the above code.

View this demo on the Codrops Playground

And a lot more!

There’s a lot more than Flexbox can do. Philip Walton has created a popular page called Solved By Flexbox, which showcases “problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox”.

Zoe Mickley Gillenwater has also given a great talk at the SmashingConf, called “Leveling Up With Flexbox“. Her presentation features a lot of practical use cases for Flexbox, along with ways to start using Flexbox today without worrying about older browsers, by providing decent fallback for these browsers. The examples shown and explained in her slides are definitely worth checking out.

You can also refer to one of the many articles in the Further reading section below for more Flexbox examples.

Browser Support

CSS Flexible Box Layout Module

Method of positioning elements in horizontal or vertical stacks. Support includes all properties prefixed with `flex`, as well as `display: flex`, `display: inline-flex`, `align-content`, `align-items`, `align-self`, `justify-content` and `order`.

W3C Candidate Recommendation

Supported from the following versions:

Desktop

  • 29
  • 28
  • 11
  • 12
  • 9

Mobile / Tablet

  • 9.0
  • 4.4
  • all
  • 122
  • 123

* denotes prefix required.

  • Supported:
  • Yes
  • No
  • Partially
  • Polyfill

Stats from caniuse.com

Notes

Over the course of time, the Flexbox syntax has changed. If you browse the web for Flexbox articles, you may stumble across articles that use a syntax that’s different from the one used in this entry. Some articles may still be using the old syntax. The syntax used in this entry is the new/latest syntax.

As you can see in the browser compatibility table, some older versions of browsers used to support the old syntax. Depending on how many browser versions you want to support, you may need to use both the old and the new Flexbox syntax.

If you want to learn more about using the older and newer syntax for wider/older browser support, you can read Advanced Cross-Browser Flexbox at the Dev.Opera Blog.

Written by . Last updated May 4, 2017 at 9:15 pm by Manoela Ilic.

Do you have a suggestion, question or want to contribute? Submit an issue.