CSS3 Flexible Box Layouts

The CSS3 Flexible Box, or flexbox, is a new layout model for creating the more flexible user interface design.

Understanding the Flex Layout Model

Flexible box, commonly referred to as flexbox, is a new layout model introduced in CSS3 for creating the flexible user interface design with multiple rows and columns without using the percentage or fixed length values. The CSS3 flex layout model provides a simple and powerful mechanism for handling the distributing of space and alignment of content automatically through stylesheet without interfering the actual markup.

The following example demonstrate how to create a three column layout where each column has equal width and height using the flex layout model.

  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  • <meta charset="utf-8">
  • <title>CSS3 Three Equal Flex Column</title>
  • <style type="text/css">
  •     .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>

If you notice the above example code carefully you'll find we didn't specify any width on the inner <div> of the .flex-container, but you can see in the output, every column has width which is exactly equal to the one third of the parent .flex-container element.


How Flex Layout Works

Flexbox consists of flex containers and flex items. A flex container can be created by setting the display property of an element to either flex (generate block-level flex container) or inline-flex (generate an inline flex container similar to inline-block). All child elements of flex container automatically become flex items and are laid out using the flex layout model. The float, clear, and vertical-align properties have no effect on flex items.

Flex items are positioned inside a flex container along a flex line controlled by the flex-direction property. By default, there is only one flex line per flex container which has the same orientation as the inline axis of the current writing mode or text direction. The following illustration will help you to understand the flex layout terminology.

Flexbox Illustration

Controlling Flow inside Flex Container

In the standard CSS box model, the elements normally displayed in the order as they appear in the underlying HTML markup. Flex layout lets you control the direction of the flow inside a flex container in such a way that the elements can be laid out in any flow direction leftwards, rightwards, downwards, or even upwards.

The flow of the flex items in a flex container can be specified using the flex-direction property. The default value of this property is row which is same as the document's current writing mode or text direction e.g. left-to-right in English language.

  • .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;
  • }

Similary, you can disply the flex items inside a flex container in columns instead of row using the value column for the flex-direction property, like this:

  • .flex-container {
  •     width: 80%;
  •     min-height: 300px;
  •     /* Safari */
  •     display: -webkit-flex;
  •     -webkit-flex-direction: column;
  •     /* Standard syntax */
  •     display: flex;
  •     flex-direction: column;
  • }

Controlling the Dimensions of Flex Items

The most important aspect of the flex layout is the ability of flex items to alter their width or height to fill the available space. This is achieved with the flex property. It is shorthand property for flex-grow, flex-shrink and flex-basis properties.

A flex container distributes the free space to its items proportional to their flex grow factor, or shrinks them to prevent overflow proportional 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 occupy 1/4 i.e. 1/(1+1+2) of the free space each, whereas the second flex item will occupy 1/2 i.e. 2/(1+1+2) of the free space. Similarly, you can create other flexible layouts using this simple technique.

 

Note:It is strongly recommended to use the shorthand rather than the individual flex properties because it resets unspecified components correctly.


Aligning Flex Items within Flex Container

There are four properties justify-content, align-content, align-items and align-self which are designed to control the alignment of flex items within flex container. The first three of them apply to flex containers whereas the last one applies to the individual flex items.

Align Flex Items along Main Axis

Flex items can be aligned along the main axis (i.e. in the horizontal direction) of the flex container using the justify-content property. It is typically used when the flex items do not use all the space available along the main axis.

The justify-content property accepts the following values:

  • flex-start — Default value. Flex items are placed at the start of the main axis.
  • flex-end — Flex items are placed at the end of the main axis.
  • center — Flex items are placed at the center of the main axis with equal amounts of free space at both ends. If the leftover free-space is negative i.e. if the items overflow, then the flex items will overflow equally in both directions.
  • space-between — Flex items are distributed evenly along the main axis, where the first item placed at the main-start edge and the last one placed at the main-end. If items overflow or there's only one item, this value is equal to flex-start.
  • space-around — Flex items are distributed evenly with half-size spaces on either end. If they overflow or there's only one item, this value is identical to center.

The following example will show you the effect of the different values for justify-content property on a multiple-column flex container having 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;
  • }

Align Flex Items along Cross Axis

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. However, where the align-items is applied to the flex container, the align-self property is applied to the individual flex items, and overrides align-items. Both properties accept the following values:

  • flex-start — Flex items are placed at the start of the cross axis.
  • flex-end — Flex items are placed at the end of the cross axis.
  • center — Flex items are placed at the center of the cross axis with equal amounts of free space at both ends. If the leftover free-space is negative i.e. if the items overflow, then the flex items will overflow equally in both directions.
  • baseline — The text baseline (or inline axis) of each flex item is aligned with the baseline of the flex item with the largest font-size.
  • stretch — The flex item stretches to fill the current row or column unless prevented by the minimum and maximum width or height. Default value for align-items property.

The following example will show you the effect of the different values for align-items property on a multiple-column flex container having 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 on the cross axis of a multiple-row or multiple-column flex container. The property align-content is used to align the flex container's lines, for example, rows within the multiple-row flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.

The align-content property accepts the same values as justify-content, but applies them to the cross axis rather than the main axis. It also accepts one more value:

  • stretch The free space is split equally between all rows or columns increasing their cross size. If the leftover free-space is negative, this value is identical to flex-start.

The following example will show you the effect of the different values for align-content property on a multiple-row flex container having 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;
  • }

Reordering Individual Flex Items

In addition to altering the flow within a flex container, you can also change the order in which individual flex items are displayed using the order property. This property accepts positive or negative integer as value. By default, all flex items are displayed and laid out in the same order as they appear in the HTML markup as the default value of order is 0.

The following example will show you how to control the order 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 item with the lowest order value laid out first, whereas the item with highest order value laid out at the end. Items with the same order value are displayed in the same order a they appear in the source document.


Horizontal and Vertical Center Alignment with Flexbox

Normally vertical alignment of a content block involves the use of JavaScript or some ugly CSS tricks. But with flexbox you can easily do this without any adjustments.

The following example will show you how to align a content block vertically and horizontally in the middle easily with the CSS3 flexible box 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;
  • }

Enable Wrapping of Flex Items

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 control whether its flex items will wrap into multiple lines or not, if there is not sufficient space for them on one flex line.

The flex-wrap property accept the following values:

  • nowrap — Default value. The flex items are placed in a single line. It may cause overflow, if there is not enough space on the flex line.
  • wrap — The flex container breaks its flex items across multiple lines, similar to how text is broken onto a new line when it is too wide to fit on the current line.
  • wrap-reverse — The flex items will wrap, if necessary, but in reverse order i.e. the cross-start and cross-end directions are swapped.

The following example will show you how to display the 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 use the shorthand CSS property flex-flow for setting both the flex-direction and flex-wrap in a single declaration. It accepts the same values as the individual properties and the values can be in any order.

 
Close

Your Feedback:

 

We would love to hear from you! Please say something.