The Flexible Box, or flexbox, is a new layout system introduced in CSS3 that allows for the creation of adaptable user interfaces with multiple rows and columns without needing to use percentage or fixed length values. The CSS3 flexbox layout provides an easy and effective way to automatically manage space distribution and content alignment via stylesheets, without changing the actual HTML structure.
The following example shows how to make a three-column layout where each column has the same width and height using the flexbox model.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CSS3 Three Equal Flex Column</title>
<style>
.flex-container {
width: 80%;
min-height: 300px;
display: -webkit-flex; /* Safari */
display: flex; /* Standard syntax */
border: 1px solid #808080;
}
.flex-container div {
background: #dbdfe5;
-webkit-flex: 1; /* Safari */
-ms-flex: 1; /* IE 10 */
flex: 1; /* Standard syntax */
}
</style>
</head>
<body>
<div class="flex-container">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
</div>
</body>
</html>
When you look closely at the example code above, you'll notice that we didn't set any width for the inner <div>
elements within the .flex-container
. However, the output shows each column having a width exactly one-third of the parent .flex-container
element.
Flexbox is made up of flex containers and flex items. You can create a flex container by setting the display
property of an element to either flex
(which creates a block-level flex container) or inline-flex
(which creates an inline flex container similar to inline-block). All child elements within a flex container become flex items and are arranged using the flex layout model. The properties float
, clear
, and vertical-align
do not affect flex items.
Flex items are arranged inside a flex container along a flex line, which is controlled by the flex-direction
property. By default, there is only one flex line per flex container, which follows the same direction as the inline axis of the current writing mode or text direction. The illustration below will help you understand the terminology used in the flex layout.
In the regular CSS box model, elements are usually displayed in the order they appear in the HTML markup. The flex layout allows you to control the flow direction inside a flex container so that elements can be laid out in any direction: left, right, down, or up.
You can set the flow of flex items in a flex container using the flex-direction
property. The default value for this property is row
, which is the same as the document's current writing mode or text direction, such as left-to-right in English.
.flex-container {
width: 80%;
min-height: 300px;
/* Safari */
display: -webkit-flex;
-webkit-flex-direction: row-reverse;
/* Standard syntax */
display: flex;
flex-direction: row-reverse;
border: 1px solid #666;
}
Similarly, you can display the flex items inside a flex container in columns instead of rows by setting the flex-direction
property to column
, like this:
.flex-container {
width: 80%;
min-height: 300px;
/* Safari */
display: -webkit-flex;
-webkit-flex-direction: column;
/* Standard syntax */
display: flex;
flex-direction: column;
}
The key feature of the flex layout is that flex items can change their width or height to fit the available space. This is done using the flex
property. It is a shorthand for the flex-grow
, flex-shrink
, and flex-basis
properties.
A flex container allocates free space to its items based on their flex grow factor or shrinks them to avoid overflow according to their flex shrink factor.
.flex-container {
width: 80%;
min-height: 300px;
display: -webkit-flex; /* Safari */
display: flex; /* Standard syntax */
}
.flex-container div {
padding: 10px;
background: #dbdfe5;
}
.item1, .item3 {
-webkit-flex: 1; /* Safari */
flex: 1; /* Standard syntax */
}
.item2 {
-webkit-flex: 2; /* Safari */
flex: 2; /* Standard syntax */
}
In the above example, the first and third flex items will each take up 1/4 or 1/(1+1+2)
of the free space, while the second flex item will occupy 1/2 or 2/(1+1+2)
of the free space. You can use this straightforward technique to create other flexible layouts as well.
Note: It's strongly advised to use the shorthand instead of individual flex properties because it ensures unspecified components are reset correctly.
There are four properties: justify-content
, align-content
, align-items
, and align-self
that control the alignment of flex items within a flex container. The first three apply to flex containers, while the last one applies to individual flex items.
Flex items can be aligned along the main axis (i.e., horizontally) of the flex container using the justify-content
property. This is usually used when the flex items don't take up all the available space along the main axis.
The justify-content
property can have the following values:
flex-start
.center
.The following example shows the effect of different justify-content
values on a multi-column flex container with a fixed width.
.flex-container {
width: 500px;
min-height: 300px;
border: 1px solid #666;
/* Safari */
display: -webkit-flex;
-webkit-justify-content: space-around;
/* Standard syntax */
display: flex;
justify-content: space-around;
}
.item1 {
width: 75px;
background: #e84d51;
}
.item2 {
width: 125px;
background: #7ed636;
}
.item3 {
width: 175px;
background: #2f97ff;
}
Flex items can be aligned along the cross axis (i.e., in the perpendicular direction) of the flex container using the align-items
or align-self
property. The align-items
property applies to the flex container, while the align-self
property applies to individual flex items, overriding align-items
. Both properties accept the following values:
font-size
.align-items
property.The following example demonstrates the effect of different align-items
values on a multi-column flex container with a fixed height.
.flex-container {
width: 500px;
min-height: 300px;
border: 1px solid #666;
/* Safari */
display: -webkit-flex;
-webkit-align-items: center;
/* Standard syntax */
display: flex;
align-items: center;
}
.item1 {
width: 75px;
height: 100px;
background: #e84d51;
}
.item2 {
width: 125px;
height: 200px;
background: #7ed636;
}
.item3 {
width: 175px;
height: 150px;
background: #2f97ff;
}
You can also distribute free space along the cross axis of a multiple-row or multiple-column flex container. The align-content
property aligns the lines of a flex container, such as rows in a multi-row flex container, when there is extra space in the cross axis. This works similarly to how justify-content
aligns items along the main axis.
The align-content
property accepts the same values as justify-content
, but applies them to the cross axis instead of the main axis. It also includes one additional value:
flex-start
.The following example shows the effect of different align-content
values on a multi-row flex container with a fixed height.
.flex-container {
width: 500px;
min-height: 300px;
margin: 0 auto;
font-size: 32px;
border: 1px solid #666;
/* Safari */
display: -webkit-flex;
-webkit-flex-flow: row wrap;
-webkit-align-content: space-around;
/* Standard syntax */
display: flex;
flex-flow: row wrap;
align-content: space-around;
}
.flex-container div {
width: 150px;
height: 100px;
background: #dbdfe5;
}
In addition to changing the arrangement within a flex container, you can also adjust the sequence in which individual flex items are shown using the order
property. This property accepts a positive or negative integer as its value. By default, all flex items are displayed and arranged in the same order as they appear in the HTML markup, with the default value of order
being 0
.
The following example illustrates how to manage the sequence of an individual flex item.
.flex-container {
width: 500px;
min-height: 300px;
border: 1px solid #666;
display: -webkit-flex; /* Safari 6.1+ */
display: flex;
}
.flex-container div {
padding: 10px;
width: 130px;
}
.item1 {
background: #e84d51;
-webkit-order: 2; /* Safari 6.1+ */
order: 2;
}
.item2 {
background: #7ed636;
-webkit-order: 1; /* Safari 6.1+ */
order: 1;
}
.item3 {
background: #2f97ff;
-webkit-order: -1; /* Safari 6.1+ */
order: -1;
}
Note: Flex items with the lowest order
value are positioned first, and those with the highest order
value are positioned last. Items with the same order
value are displayed in the order they appear in the source document.
Traditionally, aligning a content block vertically involves using JavaScript or complex CSS workarounds. But with flexbox, you can easily achieve this without any additional adjustments.
The following example illustrates how to centrally align a content block both vertically and horizontally using the CSS3 flexbox feature.
.flex-container {
width: 500px;
min-height: 300px;
border: 1px solid #666;
display: -webkit-flex; /* Safari 6.1+ */
display: flex; /* Standard syntax */
}
.item {
width: 300px;
padding: 25px;
margin: auto;
background: #f0e68c;
}
By default, flex containers display only a single row or column of flex items. However, you can use the flex-wrap
property on the flex container to determine whether its flex items will wrap into multiple lines if there isn't enough space for them on one flex line.
The flex-wrap
property accepts the following options:
The following example demonstrates how to arrange flex items in a single or multiple lines within a flex container using the flex-wrap
property.
.flex-container {
width: 500px;
min-height: 300px;
border: 1px solid #666;
/* Safari */
display: -webkit-flex;
-webkit-flex-wrap: wrap;
/* Standard syntax */
display: flex;
flex-wrap: wrap;
}
.flex-container div{
width: 130px;
padding: 10px;
background: #dbdfe5;
}
Note: You can also employ the shorthand CSS property flex-flow
to define both the flex-direction
and flex-wrap
in a single declaration. It supports the same values as the individual properties, and you can place these values in any order.