Using CSS flexible boxes

  • Revision slug: CSS/Using_CSS_flexible_boxes
  • Revision title: Using CSS flexible boxes
  • Revision id: 235122
  • Created:
  • Creator: scottrowe
  • Is current revision? No
  • Comment 2 words added, 2 words removed

Revision Content

{{ SeeCompatTable() }}

CSS Flexible Box Layout Model, also known as "flexbox", is a part of the draft CSS3 specification. It provides a CSS Box Model optimized for user interface design. Children in the flex layout can be laid out in any direction and have flexible dimensions to adapt with the space available. Positionning those children can be accomplished easily, and complex layout can be achieved in a simpler and cleaner way. The display order of the elements is independent from the order in the source code.

Note: CSS Flexible Boxes Layout specfication is still a draft so all properties used should be prefixed with -ms-, -moz-, -o- and -webkit- to make sure of browser compatibility with respectively Internet Explorer, Gecko, Opera and Webkit browsers.

See Flexbox for an introduction to the API.

Flexible boxes concept

The flexbox layout algorithm is direction-agnostic as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased. While the block layout works well for pages, it lacks sufficient definition to support application components that have to change orientation, resize, stretch, or shrink as the user agent changes, flips from vertical to horizontal, and so forth.  Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the (emerging) Grid layout is intended for larger scale layouts. Both are part of a wider effort with CSS3 to provide for greater interoperability of web applications with different user agents, different writing modes, and other demands on flexibility.

Flexible boxes vocabulary

While a discussion of flexible boxes is liberated from terms like horizontal/in-line axis and vertical/block axis, it requires a new terminology to properly describe the model. Consider the following diagram when reviewing the vocabulary items below. It shows a flex container that has a flex-direction of row, meaning that the flex items follow each other horizontally across the main axis according to the established writing mode, the direction in which the element's text flows, in this case left-to-right.

flex_terms.png

Flex container
The parent element in which flex items are contained. A flex container is defined using the flex or inline-flex values of the display property.
Flex item

Flex items are elements that match one of the following criteria:

  • A block-level child of a flex container.
  • Atomic inline-level child of a flex container.
  • An HTML {{ HTMLElement("img") }}, {{ HTMLElement("canvas") }}, {{ HTMLElement("svg") }}, {{ HTMLElement("math") }}, {{ HTMLElement("audio") }}, {{ HTMLElement("video") }}, {{ HTMLElement("iframe") }}, {{ HTMLElement("object") }}, {{ HTMLElement("embed") }}, {{ HTMLElement("applet") }}, {{ HTMLElement("progress") }}, {{ HTMLElement("meter") }}, {{ HTMLElement("input") }}, {{ HTMLElement("button") }}, {{ HTMLElement("select") }} or {{ HTMLElement("textarea") }} element.
  • An anonymous block wrapping contiguous non-replaced inline children.
Note: If the anonymous block contains solely inline containing whitespaces, the box would not be generated as if it had display:none.
Note: Absolutely positioned children of a flex container are not considered flex items, but instead leave an anonymous inline box with a width and height and line-height of 0. When justify-content property is set to space-between or space-around, this can cause a double-sized space between items.
Axes

Every flexible box layout follows two axes. The main axis is the axis along which the flex items follow each other. The cross axis is the axis perpendicular to the main axis.

  • The flex-direction property establishes the main axis.
  • The justify-content property defines how flex items are laid out along the main axis on the current line.
  • The align-items property defines the default for how flex items are laid out along the cross axis on the current line.
  • The align-self property defines how a single flex item is aligned on the cross axis, and overrides the default established by align-items.
Directions

The main start/main end and cross start/cross end sides pairs of the flex container describe the origin and terminus of the flow of flex items. They follow the main axis and cross axis of the flex container in the vector established by the writing-mode (left-to-right, right-to-left, etc.).

  • The order property assigns elements to ordinal groups and determines which elements appear first.
  • The flex-flow property shorthands the flex-direction and flex-wrap properties to lay out the flex items.
Lines

Flex items can be laid out on either a single line or on several lines according to the flex-wrap property, which controls the direction of the cross axis and the direction in which new lines are stacked.

Dimensions

The flex items' agnostic equivalents of height and width are main size and cross size, which respectively follow the main axis and cross axis of the flex container.

Designating a flexible box

To designate the CSS for elements using this style, set the display property as follows:

display :  flex

or

display : inline-flex

Doing so defines the element as a flex container and its children as flex items. The flex value makes the flex container a block-level element. The inline-flex value makes the flex container an atomic inline-level element.

Note: For the vendor prefix tag, append the string on the display property (not on the display attribute itself). For example, display : -webkit-flex.

Flexible box properties

{{ page{path: "/en/CSS/Flexbox", section: "flex- properties"} }}

Properties not affecting flexible boxes

Since flexible boxes uses a different layout algorithm, some properties do not make sense on a flex container.

  • column-* properties of the Multicol module have no effect on a flex.
  • float and clear have no effect on a flex item. Using float cause the display property of the element to compute to block.
  • vertical-align has no effect on the alignment of flex items.

Simple Example

This simple example runs in Chrome version 21 (Chrome Canary, currently, which you can install in addition to Chrome). So you can run the example by creating a file with the following code and loading it in Chrome Canary.

​<!DOCTYPE html>
<html lang="en">
  <head>
    <style>

   .flex {
  /* basic styling */
        width: 700px;
        height: 400px;
        border: 1px solid #555;
        font: 14px Arial;

  /* flexbox setup */
        display: -webkit-flex;
        -webkit-flex-direction: row;
     
        display: -moz-flex;
        -moz-flex-direction: row;
     
        display: flex;
        -flex-direction: row;
   }

   .flex > div {
        -webkit-flex: 1 1 auto;
        -moz-flex: 1 1 auto;
        flex: 1 1 auto;

        -moz-transition: width 0.7s ease-out;
        -o-transition: width 0.7s ease-out;
        -webkit-transition: width 0.7s ease-out;
        transition: width 0.7s ease-out;
   }

   /* colors */
        .flex > div:nth-child(1){ background : #009246; }
        .flex > div:nth-child(2){ background : #F1F2F1; }
        .flex > div:nth-child(3){ background : #CE2B37; }

        .flex > div:hover {
        width: 200px;
   }
   
    </style>
    
 </head>
 <body>
  <p>Flexbox nuovo </p>
  <div class="flex">
    <div>uno</div>
    <div>due</div>
    <div>tre</div>
  </div>
 </body>
</html>

Things to keep in mind

The algorithm describing how flex items are laid out can be pretty tricky at times. Here are a few things to consider to avoid bad surprises when designing using flexible boxes.

Flexibles boxes are laid out in conformance of the writing mode. Which means that main start and main end are laid out according to the position of start and end.

cross start and cross end rely on the definition of the start or before position that depends on the value of direction.

Page breaks are possible in flexible boxes layout as long as break- property allows it. CSS3 break-after, break-before and break-inside as well as CSS 2.1   page-break-before, page-break-after and page-break-inside properties are accepted on a flex container, flex items and inside flex items.

Browser compatibility

{{ CompatibilityTable() }}

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support {{ CompatUnknown() }} 21.0{{ property_prefix("-webkit") }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}
Feature Firefox Mobile (Gecko) Android IE Phone Opera Mobile Safari Mobile
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}

Revision Source

<p>{{ SeeCompatTable() }}</p>
<p>CSS Flexible Box Layout Model, also known as "flexbox", is a part of the draft CSS3 specification. It provides a CSS Box Model optimized for user interface design. Children in the flex layout can be laid out in any direction and have flexible dimensions to adapt with the space available. Positionning those children can be accomplished easily, and complex layout can be achieved in a simpler and cleaner way. The display order of the elements is independent from the order in the source code.</p>
<div class="note">Note: CSS Flexible Boxes Layout specfication is still a draft so all properties used should be prefixed with <code>-ms-</code>, <code>-moz-</code>, <code>-o-</code> and <code>-webkit-</code> to make sure of browser compatibility with respectively Internet Explorer, Gecko, Opera and Webkit browsers.</div>
<p>See <a href="/en/CSS/Flexbox" title="/en/CSS/Flexbox">Flexbox</a> for an introduction to the API.</p>
<h2>Flexible boxes concept</h2>
<p>The flexbox layout algorithm is direction-agnostic as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased. While the block layout works well for pages, it lacks sufficient definition to support application components that have to change orientation, resize, stretch, or shrink as the user agent changes, flips from vertical to horizontal, and so forth.  Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the (emerging) Grid layout is intended for larger scale layouts. Both are part of a wider effort with CSS3 to provide for greater interoperability of web applications with different user agents, different writing modes, and other demands on flexibility.</p>
<h2>Flexible boxes vocabulary</h2>
<p>While a discussion of flexible boxes is liberated from terms like horizontal/in-line axis and vertical/block axis, it requires a new terminology to properly describe the model. Consider the following diagram when reviewing the vocabulary items below. It shows a flex container that has a <code>flex-direction</code> of <code>row</code>, meaning that the flex items follow each other horizontally across the main axis according to the established writing mode, the direction in which the element's text flows, in this case left-to-right.</p>
<p><img alt="flex_terms.png" class="internal default" src="/@api/deki/files/6298/=flex_terms.png" style=""></p>
<dl> <dt>Flex container</dt> <dd>The parent element in which flex items are contained. A flex container is defined using the <code>flex</code> or <code>inline-flex</code> values of the <a href="/en/CSS/display" rel="internal" title="display"><code>display</code></a> property.</dd> <dt>Flex item</dt> <dd> <p>Flex items are elements that match one of the following criteria:</p> <ul> <li>A block-level child of a flex container.</li> <li><a href="/en/CSS/Visual_formatting_model#Inline-level_elements_and_inline_boxes" title="en/CSS/Visual_formatting_model#Inline-level_elements_and_inline_boxes">Atomic inline-level</a> child of a flex container.</li> <li>An HTML {{ HTMLElement("img") }}, {{ HTMLElement("canvas") }}, {{ HTMLElement("svg") }}, {{ HTMLElement("math") }}, {{ HTMLElement("audio") }}, {{ HTMLElement("video") }}, {{ HTMLElement("iframe") }}, {{ HTMLElement("object") }}, {{ HTMLElement("embed") }}, {{ HTMLElement("applet") }}, {{ HTMLElement("progress") }}, {{ HTMLElement("meter") }}, {{ HTMLElement("input") }}, {{ HTMLElement("button") }}, {{ HTMLElement("select") }} or {{ HTMLElement("textarea") }} element.</li> <li>An anonymous block wrapping contiguous non-replaced inline children.</li> </ul> <div class="note"><strong>Note: </strong>If the anonymous block contains solely inline containing whitespaces, the box would not be generated as if it had <code>display:none</code>.</div> <div class="note"><strong>Note:</strong> Absolutely positioned children of a flex container are not considered flex items, but instead leave an anonymous inline box with a <span id="cke_bm_265S" style="display: none;"> </span><code>width</code><span id="cke_bm_265E" style="display: none;"> </span> and <code>height</code> and <code>line-height</code> of <span id="cke_bm_266E" style="display: none;"> </span><code>0</code>. When <code>justify-content</code> property is set to <code>space-between</code> or <code>space-around</code>, this can cause a double-sized space between items.</div> </dd> <dt>Axes</dt> <dd> <p>Every flexible box layout follows two axes. The <strong>main axis</strong> is the axis along which the flex items follow each other. The <strong>cross axis</strong> is the axis perpendicular to the <strong>main axis</strong>.</p> <ul> <li>The <code><a href="/en/CSS/flex-direction" rel="internal" title="flex-direction">flex-direction</a></code> property establishes the main axis.</li> <li>The <a href="/en/CSS/justify-content" rel="internal" title="en/CSS/justify-content"><code>justify-content</code></a> property defines how flex items are laid out along the main axis on the current line.</li> <li>The <a href="/en/CSS/align-items" title="en/CSS/align-items"><code>align-items</code></a> property defines the default for how flex items are laid out along the cross axis on the current line.</li> <li>The <a href="/en/CSS/align-self" title="en/CSS/align-self"><code>align-self</code></a> property defines how a single flex item is aligned on the cross axis, and overrides the default established by <code>align-items.</code></li> </ul> </dd> <dt>Directions</dt> <dd> <p>The <strong>main start</strong>/<strong>main end </strong>and <strong>cross start</strong>/<strong>cross end</strong> sides pairs of the flex container describe the origin and terminus of the flow of flex items. They follow the main axis and cross axis of the flex container in the vector established by the <code>writing-mode</code> (left-to-right, right-to-left, etc.).</p> <ul> <li>The <a href="/en/CSS/order" rel="internal" title="en/CSS/order"><code>order</code></a> property assigns elements to ordinal groups and determines which elements appear first.</li> <li>The <a href="/en/CSS/flex-flow" rel="internal" title="flex-flow"><code>flex-flow</code></a> property shorthands the <a href="/en/CSS/flex-direction" rel="internal" title="flex-direction"><code>flex-direction</code></a> and <a href="/en/CSS/flex-wrap" rel="internal" title="flex-wrap"><code>flex-wrap</code></a> properties to lay out the flex items.</li> </ul> </dd> <dt>Lines</dt> <dd> <p>Flex items can be laid out on either a single line or on several lines according to the <a href="/en/CSS/flex-wrap" rel="internal" title="flex-wrap"><code>flex-wrap</code></a> property, which controls the direction of the cross axis and the direction in which new lines are stacked.</p> </dd> <dt>Dimensions</dt> <dd> <p>The flex items' agnostic equivalents of height and width are <strong>main size</strong> and <strong>cross size,</strong> which respectively follow the main axis and cross axis of the flex container.</p> <ul> <li>The <code><a href="/en/CSS/min-height" title="/en/CSS/min-height">min-height</a></code> and <code><a href="/en/CSS/min-width" title="/en/CSS/min-width">min-width</a></code> properties have a new value, <code>auto</code> that establishes the minimum size of a flex item.</li> <li>The <a href="/en/CSS/flex" rel="internal" title="en/CSS/flex"><code>flex</code></a> property shorthands the <code><a href="/en/CSS/flex-basis" rel="internal" title="en/CSS/flex-basis">flex-basis</a></code>, <a href="/en/CSS/flex-grow" rel="internal" title="en/CSS/flex-grow"><code>flex-grow</code></a>, and <a href="/en/CSS/flex-shrink" rel="internal" title="en/CSS/flex-shrink"><code>flex-shrink</code></a> properties to establish the flexibility of the flex items.</li> </ul> </dd>
</dl><h2>Designating a flexible box</h2>
<p>To designate the CSS for elements using this style, set the <a href="/en/CSS/display" title="/en/CSS/display">display</a> property as follows:</p>
<pre>display :  flex</pre>
<p>or</p>
<pre>display : inline-flex</pre>
<p>Doing so defines the element as a flex container and its children as flex items. The <code>flex</code> value makes the flex container a block-level element. The <code>inline-flex</code> value makes the flex container an atomic inline-level element.</p>
<div class="note">Note: For the vendor prefix tag, append the string on the display property (not on the display attribute itself). For example, <code>display : -webkit-flex</code>.</div><h2>Flexible box properties</h2>
<p><span id="cke_bm_69S" style="display: none; "> </span>{{ page{path: "/en/CSS/Flexbox", section: "flex- properties"} }}<span id="cke_bm_69E" style="display: none; "> </span></p>
<dl>
</dl>
<h3>Properties not affecting flexible boxes</h3>
<p>Since flexible boxes uses a different layout algorithm, some properties do not make sense on a flex container.</p>
<ul> <li>column-* properties of the <a href="/en/CSS/Using_CSS_multi-column_layouts" title="Using CSS multi-column layouts">Multicol module</a> have no effect on a flex.</li> <li><a href="/en/CSS/float" title="float"><code>float</code></a> and <a href="/en/CSS/clear" title="clear"><code>clear</code></a> have no effect on a flex item. Using <code>float</code> cause the <code>display</code> property of the element to compute to <code>block</code>.</li> <li><a href="/en/CSS/vertical-align" title="vertical-align"><code>vertical-align</code></a> has no effect on the alignment of flex items.</li>
</ul>
<h2>Simple Example</h2>
<p>This simple example runs in Chrome version 21 (Chrome Canary, currently, which you can install in addition to Chrome). So you can run the example by creating a file with the following code and loading it in Chrome Canary.</p>
<pre>​&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;style&gt;

   .flex {
  /* basic styling */
        width: 700px;
        height: 400px;
        border: 1px solid #555;
        font: 14px Arial;

  /* flexbox setup */
        display: -webkit-flex;
        -webkit-flex-direction: row;
     
        display: -moz-flex;
        -moz-flex-direction: row;
     
        display: flex;
        -flex-direction: row;
   }

   .flex &gt; div {
        -webkit-flex: 1 1 auto;
        -moz-flex: 1 1 auto;
        flex: 1 1 auto;

        -moz-transition: width 0.7s ease-out;
        -o-transition: width 0.7s ease-out;
        -webkit-transition: width 0.7s ease-out;
        transition: width 0.7s ease-out;
   }

   /* colors */
        .flex &gt; div:nth-child(1){ background : #009246; }
        .flex &gt; div:nth-child(2){ background : #F1F2F1; }
        .flex &gt; div:nth-child(3){ background : #CE2B37; }

        .flex &gt; div:hover {
        width: 200px;
   }
   
    &lt;/style&gt;
    
 &lt;/head&gt;
 &lt;body&gt;
  &lt;p&gt;Flexbox nuovo &lt;/p&gt;
  &lt;div class="flex"&gt;
    &lt;div&gt;uno&lt;/div&gt;
    &lt;div&gt;due&lt;/div&gt;
    &lt;div&gt;tre&lt;/div&gt;
  &lt;/div&gt;
 &lt;/body&gt;
&lt;/html&gt;</pre>
<h2>Things to keep in mind</h2>
<p>The algorithm describing how flex items are laid out can be pretty tricky at times. Here are a few things to consider to avoid bad surprises when designing using flexible boxes.</p>
<p>Flexibles boxes are laid out in conformance of the <a href="/pl/XUL/Własność/mode" title="mode">writing mode</a>. Which means that <strong>main start</strong> and <strong>main end</strong> are laid out according to the position of <strong>start</strong> and <strong>end</strong>.</p>
<p><strong>cross start</strong> and <strong>cross end</strong> rely on the definition of the <strong>start</strong> or <strong>before</strong> position that depends on the value of <a href="/en/CSS/direction" title="direction"><code>direction</code></a>.</p>
<p>Page breaks are possible in flexible boxes layout as long as <code>break-</code> property allows it. CSS3 <code>break-after</code>, <code>break-before</code> and <code>break-inside</code> as well as CSS 2.1   <code>page-break-before</code>, <code>page-break-after</code> and <code>page-break-inside</code> properties are accepted on a flex container, flex items and inside flex items.</p><h2>Browser compatibility</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop"> <table class="compat-table"> <tbody> <tr> <th>Feature</th> <th>Firefox (Gecko)</th> <th>Chrome</th> <th>Internet Explorer</th> <th>Opera</th> <th>Safari</th> </tr> <tr> <td>Basic support</td> <td>{{ CompatUnknown() }}</td> <td>21.0{{ property_prefix("-webkit") }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> </tr> </tbody> </table>
</div>
<div id="compat-mobile"> <table class="compat-table"> <tbody> <tr> <th>Feature</th> <th>Firefox Mobile (Gecko)</th> <th>Android</th> <th>IE Phone</th> <th>Opera Mobile</th> <th>Safari Mobile</th> </tr> <tr> <td>Basic support</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> </tr> </tbody> </table>
</div>
Revert to this revision