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:
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
orheight
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
orheight
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
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.
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.
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
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.
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.
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:
The justify-content
Property
justify-content: flex-start | flex-end | center | space-between | space-around
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.
The align-items
Property
align-items: flex-start | flex-end | center | baseline | stretch
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).
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
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.
Flexbox Properties: Flex Items Properties
The order
Property
order: <integer>
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 PlaygroundThe align-self
Property
align-self: auto | flex-start | flex-end | center | baseline | stretch
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 ofalign-items
on the element’s container, orstretch
if the element has no parent. In other words, the item will be aligned based on the default value or the value specified for thealign-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.
The flex-grow
Property
flex-grow: <number>
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.
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.
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.
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 thewidth
/height
properties. (If the item’s main size property computes toauto
, 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 thewidth
/height
properties, but makes them fully flexible, so that they absorb any free space along the main axis. If all items are eitherflex: auto
,flex: initial
, orflex: none
, any positive free space after the items have been sized will be distributed evenly to the items withflex: auto
. - flex: none
-
This is equivalent to
flex: 0 0 auto
. This value sizes the item according to thewidth
/height
properties, but makes the flex item fully inflexible. This is similar toinitial
, 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.
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 PlaygroundEqual-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.
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 PlaygroundFlexible 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 PlaygroundAnd 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
- 130
- 130
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.
Further Reading
- CSS Flexible Box Layout Module Level 1
- An Introduction to the CSS Flexbox Module
- Solved By Flexbox
- The Ultimate Flexbox Cheat Sheet
- Tool: Flexplorer
- Flexbox — Fast Track to Layout Nirvana?
- CSS3 Flexible Box Layout Explained
- Designing CSS Layouts With Flexbox Is As Easy As Pie
- Leveling Up With Flexbox
- Flexbox Adventures by Chris Wright
- Using Flexbox Today by Chris Wright
- A community-curated list of flexbox issues and cross-browser workarounds for them on Github.