Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
The specification describes a CSS box model optimized for user interface design. In the flex layout model, the children of a flex container can be laid out in any direction, and can "flex" their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.
This is a public copy of the editors' draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don't cite this document other than as work in progress.
The (archived) public mailing list www-style@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “css3-flexbox” in the subject, preferably like this: “[css3-flexbox] …summary of comment…”
This document was produced by the CSS Working Group (part of the Style Activity).
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
The CR period will last at least until 20 March 2013. At the time of publication, no test suite and implementation report have yet been made. They will be made available from the CSS test suites page. See the section “CR exit criteria” for details.
See the section “Changes” for changes made to this specification since the last Working Draft.
The following features are at-risk:
flex’ and ‘inline-flex’ ‘display’
values
This section is not normative.
CSS 2.1 defined four layout modes — algorithms which determine the size and position of boxes based on their relationships with their sibling and ancestor boxes:
This module introduces a new layout mode, flex layout, which is designed for laying out more complex applications and webpages.
This section is not normative.
Flex layout is superficially similar to block layout. It lacks many of the more complex text- or document-centric properties that can be used in block layout, such as floats and columns. In return it gains simple and powerful tools for distributing space and aligning content in ways that webapps and complex web pages often need. The contents of a flex container:
Here's an example of a catalog where each item has a title, an photo, a description, and a purchase button. The designer's intention is that each entry has the same overall size, that the photo be above the text, and that the purchase buttons aligned at the bottom, regardless of the length of the item's description. Flex layout makes many aspects of this design easy:
order’ is used to pull
the image up from later in the content to the top, and ‘align-self’ is used
to center it horizontally.
auto’
margin above the purchase button forces it to the bottom within each
entry box, regardless of the height of that item's description.
<style>
#deals {
display: flex; /* Flex layout so items have equal height */
flex-flow: row wrap; /* Allow items to wrap into multiple lines */
}
.sale-item {
display: flex; /* Lay out each item using flex layout */
flex-flow: column; /* Lay out item's contents vertically */
}
.sale-item > img {
order: -1; /* Shift image before other content (in visual order) */
align-self: center; /* Center the image cross-wise (horizontally) */
}
.sale-item > button {
margin-top: auto; /* Auto top margin pushes button to bottom */
}
</style>
<section id='deals'>
<section class='sale-item'>
<h1>Computer Starter Kit</h1>
<p>This is the best computer money can buy, if you don't have much money.
<ul>
<li>Computer
<li>Monitor
<li>Keyboard
<li>Mouse
</ul>
<img src='images/computer.jpg'
alt='You get: a white computer with matching peripherals.'>
<button>BUY NOW</button>
</section>
<section class='sale-item'>
…
</section>
…
</section>
This is the best computer money can buy, if you don't have much money.
Only capable of printing ASCII art.
This module extends the definition of the ‘display’ property [CSS21], adding a new block-level and
new inline-level display type, and defining a new type of formatting
context along with properties to control its layout. None of the
properties defined in this module apply to the ‘::first-line’ or ‘::first-letter’ pseudo-elements.
This specification follows the CSS property definition conventions from [CSS21]. Value types not defined in this specification are defined in CSS Level 2 Revision 1 [CSS21]. Other CSS modules may expand the definitions of these value types: for example [CSS3VAL], when combined with this module, expands the definition of the <length> value type as used in this specification.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification also accept the ‘inherit’ keyword as their property value. For
readability it has not been repeated explicitly.
An element with ‘display:flex’ or ‘display:inline-flex’ is a flex container. Children of a flex
container are called flex items and are
laid out using the flex layout model.
Unlike block and inline layout, whose layout calculations are biased to
the block
and inline flow directions, flex layout is biased to the flex flow directions. To make it easier to
talk about flex layout, this section defines a set of flex flow–relative
terms. The ‘flex-flow’ value determines how these terms
map to physical directions (top/right/bottom/left), axes
(vertical/horizontal), and sizes (width/height).
row’ flex
container.
width’ or ‘height’ property, whichever is in the main dimension.
width’ or ‘height’ that is in the cross dimension.
flex’ and ‘inline-flex’
‘display’ values| Name: | display |
|---|---|
| New Values: | flex | inline-flex |
flex’
inline-flex’
A flex container establishes a new flex formatting context for its contents.
This is the same as establishing a block formatting context, except that
flex layout is used instead of block layout: floats do not intrude into
the flex container, and the flex container's margins do not collapse with
the margins of its contents. Flex
containers form a containing block for their contents exactly
like block containers do. [CSS21] The ‘overflow’ property applies to flex containers.
Flex containers are not block containers, and so some properties that were designed with the assumption of block layout don't apply in the context of flex layout. In particular:
column-*’ properties in the
Multicol module have no effect on a flex container.
float’ and ‘clear’ have no effect on a flex item. (However, the ‘float’ property still affects the computed value
of ‘display’ on children of a flex
container, as this occurs before flex items are determined.)
vertical-align’ has no effect on a
flex item.
::first-line’ and ‘::first-letter’ pseudo-elements do not apply to flex containers.
If an element's specified ‘display’ is
‘inline-flex’ and the element is floated or
absolutely positioned, the computed value of ‘display’ is ‘flex’. The table in CSS 2.1 Chapter
9.7 is thus amended to contain an additional row, with ‘inline-flex’ in
the "Specified Value" column and ‘flex’ in the "Computed Value" column.
The contents of a flex container
consists of zero or more flex
items: each in-flow child of a flex
container becomes a flex item, and
each contiguous run of text that is directly contained inside a flex container is wrapped in an
anonymous flex item element. However, an
anonymous flex item that contains only white
space is not rendered, as if it were ‘display:none’.
Authors reading this spec may want to skip past these box-generation details.
A flex item establishes a new
formatting context for its contents. The type of this formatting context
is determined by its ‘display’ value, as
usual. The computed ‘display’ of a flex item is determined by applying the table
in CSS 2.1
Chapter 9.7. However, flex items are flex-level boxes, not block-level
boxes: they participate in their container's flex formatting context, not
in a block formatting context.
The ‘display’ computation on
flex items as defined here is expected to be superseded by a future
specification that defines a new ‘display’
value specific to flex items.
Examples of flex items:
<div style="display:flex">
<!-- flex item: block child -->
<div id="item1">block</div>
<!-- flex item: floated element; floating is ignored -->
<div id="item2" style="float: left;">float</div>
<!-- flex item: anonymous block box around inline content -->
anonymous item 3
<!-- flex item: inline child -->
<span>
item 4
<!-- flex items do not split around blocks -->
<div id=not-an-item>item 4</div>
item 4
</span>
</div>
Some values of ‘display’ trigger the
generation of anonymous boxes. For example, a misparented ‘table-cell’ child is fixed up by generating
anonymous ‘table’ and ‘table-row’ elements around it. [CSS21] This fixup must occur
before a flex container's children are promoted to flex items. For example, given two contiguous
child elements with ‘display:table-cell’, an
anonymous table wrapper box around them becomes the flex item.
Future display types may generate anonymous containers (e.g. ruby) or otherwise mangle the box tree (e.g. run-ins). It is intended that flex item determination run after these operations.
On a flex item with ‘display:
table’, the table wrapper box becomes the flex item, and the ‘order’ and ‘align-self’ properties apply to it. The
contents of any caption boxes contribute to the calculation of the table
wrapper box's min-content and max-content sizes. However, like ‘width’ and ‘height’, the ‘flex’ longhands apply to the table box as
follows: the flex item's final size
is calculated by performing layout as if the distance between the table
wrapper box's edges and the table box's content edges were all part of the
table box's border+padding area, and the table box were the flex item.
An absolutely-positioned child element of a flex container does not participate in
flex layout beyond the reordering step.
However, if both ‘left’ and ‘right’ or both ‘top’ and ‘bottom’
are ‘auto’, then the used value of those
properties are computed from its static
position, as follows:
If both ‘left’ and ‘right’ are ‘auto’, the
absolutely-positioned child must be positioned so that its main-start or cross-start edge (whichever is in the
horizontal axis) is aligned with the static position. If both
‘top’ and ‘bottom’ are ‘auto’, the
absolutely-positioned child must be positioned so that its main-start or cross-start edge (whichever is in the
vertical axis) is aligned with the static position.
In the main axis,
justify-content’ on the flex container as if the static position were
represented by a single zero-sized flex
item.
In the cross axis,
The static position is intended to more-or-less match the
position of an anonymous 0×0 in-flow ‘flex-start’-aligned flex item that participates in
flex layout, the primary difference being that any packing spaces due to
‘justify-content: space-around’ or ‘justify-content: space-between’ are suppressed around
the hypothetical item: between it and the next item if there is a real
item after it, else between it and the previous item (if any) if there
isn't.
The margins of adjacent flex items do
not collapse. Auto margins absorb extra space in the corresponding
dimension and can be used for alignment and to push adjacent flex items
apart; see Aligning with ‘auto’ margins.
Percentage margins and paddings on flex items are always resolved against their respective dimensions; unlike blocks, they do not always resolve against the inline dimension of their containing block.
Flex items paint exactly the same as
block-level elements, except that ‘order’-modified document order is used in
place of raw document order, and ‘z-index’ values other than ‘auto’ create a stacking context even if ‘position’ is ‘static’.
Note: Descendants that are positioned outside a flex item still participate in any stacking context established by the flex item.
Specifying ‘visibility:collapse’ on a flex
item causes it to become a collapsed flex item, producing
an effect similar to ‘visibility:collapse’ on a
table-row or table-column: the collapsed element is removed from rendering
entirely, but leaves behind a "strut" that keeps the flex line's
cross-size stable. Thus, if a flex container has only one flex line,
dynamically collapsing or uncollapsing items is guaranteed to have no
effect on the flex container's cross size
and won't cause the rest of the page's layout to "wobble". Flex line
wrapping is re-done after collapsing, however, so the cross-size
of a flex container with multiple lines might or might not change.
Though collapsed flex items aren't rendered, they do appear in the formatting
structure. Therefore, unlike on ‘display:none’ items [CSS21], effects that depend on an
element appearing in the formatting structure (like incrementing counters
or running animations and transitions) still operate on collapsed items.
In the following example, a sidebar is sized to fit its content.
‘Visibility: collapse’ is used to dynamically
hide parts of a navigation sidebar without affecting its width, even
though the widest item (“Architecture”) is in a collapsed section.
<style>
@media (min-width: 60em) {
/* two column layout only when enough room (relative to default text size) */
header + div { display: flex; }
#main {
flex: 1; /* Main takes up all remaining space */
order: 1; /* Place it after (to the right of) the navigation */
min-width: 12em; /* Optimize main content area sizing */
}
}
/* menu items use flex layout so that visibility:collapse will work */
nav > ul > li {
display: flex;
flex-flow: column;
}
/* dynamically collapse submenus when not targetted */
nav > ul > li:not(:target):not(:hover) > ul {
visibility: collapse;
}
</style>
…
</header>
<div>
<article id="main">
Interesting Stuff to Read
</article>
<nav>
<ul>
<li id="nav-about"><a href="#nav-about">About</a>
…
<li id="nav-projects"><a href="#nav-projects">Projects</a>
<ul>
<li><a href="…">Art</a>
<li><a href="…">Architecture</a>
<li><a href="…">Music</a>
</ul>
<li id="nav-interact"><a href="#nav-interact">Interact</a>
…
</ul>
</nav>
</div>
<footer>
…
To compute the size of the strut, flex layout is first performed with
all items uncollapsed, and then re-run with each collapsed item replaced
by a strut that maintains the original cross-size of the item's original
line. See the Flex Layout Algorithm for
the normative definition of how ‘visibility:collapse’ interacts with flex layout.
Note that using ‘visibility:collapse’ on any flex items will cause the
flex layout algorithm to repeat partway through, re-running the most
expensive steps. It's recommended that authors continue to use ‘display:none’ to hide items if the items will not be
dynamically collapsed and uncollapsed, as that is more efficient for the
layout engine. (Since only part of the steps need to be repeated when
‘visibility’ is changed, however, ‘visibility: collapse’ is still recommended for dynamic
cases.)
The contents of a flex container can be laid out in any direction and
in any order. This allows an author to trivially achieve effects that
would previously have required complex or fragile methods, such as hacks
using the ‘float’ and ‘clear’ properties. This functionality is exposed
through the ‘flex-direction’, ‘flex-wrap’, and ‘order’ properties.
The reordering capabilities of flex layout intentionally affect only the visual rendering, leaving speech order and navigation based on the source order. This allows authors to manipulate the visual presentation while leaving the source order intact for non-CSS UAs and for linear models such as speech and sequential navigation. See Reordering and Accessibility and the Flex Layout Overview for examples that use this dichotomy to improve accessibility.
Authors must not use these techniques as a substitute for correct source ordering, as that can ruin the accessibility of the document.
flex-direction’ property| Name: | flex-direction |
|---|---|
| Value: | row | row-reverse | column | column-reverse |
| Initial: | row |
| Applies to: | flex containers |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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.
row’
row-reverse’
row’, except the main-start and main-end directions are swapped.
column’
column-reverse’
column’, except the main-start and main-end directions are swapped.
The reverse values do not reverse box ordering; like
‘writing-mode’ and ‘direction’ [CSS3-WRITING-MODES],
they only change the direction of flow. Painting order, speech order, and
sequential navigation orders are not affected.
flex-wrap’ property| Name: | flex-wrap |
|---|---|
| Value: | nowrap | wrap | wrap-reverse |
| Initial: | nowrap |
| Applies to: | flex containers |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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.
nowrap’
wrap’
wrap-reverse’
wrap’, except the cross-start and cross-end directions are swapped.
flex-flow’ shorthand| Name: | flex-flow |
|---|---|
| Value: | <‘flex-direction’> || <‘flex-wrap’>
|
| Initial: | see individual properties |
| Applies to: | flex containers |
| Inherited: | see individual properties |
| Computed value: | see individual properties |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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.
Some examples of valid flows in an English (left-to-right, horizontal writing mode) document:
div { flex-flow: row; }
/* Initial value. Main-axis is
inline, no wrap. */
| |
div { flex-flow: column wrap; }
/* Main-axis is block-direction (top to bottom)
and lines wrap in the inline direction (rightwards). */
| |
div { flex-flow: row-reverse wrap-reverse; }
/* Main-axis is the opposite of inline direction
(right to left). New lines wrap upwards. */
|
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:
| English | Japanese |
|---|---|
flex-flow: row wrap; |
flex-flow: row wrap; |
order’ property 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.
| Name: | order |
|---|---|
| Value: | <integer> |
| Initial: | 0 |
| Applies to: | flex items and absolutely-positioned flex container children |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | yes |
| Canonical Order: | per grammar |
The ‘order’
property controls the order in which flex items appear within their flex
container, by assigning them to ordinal groups.
A flex container will lay out its content 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. This also affects the painting order [CSS21], exactly as if the elements were reordered in the document.
The following figure shows a simple tabbed interface, where the tab for the active pane is always first:

This could be implemented with the following CSS (showing only the relevant code):
.tabs {
display: flex;
}
.tabs > * {
min-width: min-content;
/* Prevent tabs from getting too small for their content. */
}
.tabs > .current {
order: -1; /* Lower than the default of 0 */
}
Unless otherwise specified by a future specification, this property has no effect on elements that are not flex items.
The ‘order’
property does not affect ordering in non-visual media (such as speech). Likewise, ‘order’ does not affect the
default traversal order of sequential navigation modes (such as cycling
through links, see e.g. ‘nav-index’ [CSS3UI] or tabindex
[HTML40]). Authors
must use ‘order’ only for visual, not logical,
reordering of content; style sheets that use ‘order’ to perform logical reordering are
non-conforming.
This is so that non-visual media and non-CSS UAs, which
typically present content linearly, can rely on a logical source order,
while ‘order’ is used
to tailor the visual order. (Since visual perception is two-dimensional
and non-linear, the desired visual order is not always logical.)
Many web pages have a similar shape in the markup, with a header on
top, a footer on bottom, and then a content area and one or two
additional columns in the middle. Generally, it's desirable that the
content come first in the page's source code, before the additional
columns. However, this makes many common designs, such as simply having
the additional columns on the left and the content area on the right,
difficult to achieve. This has been addressed in many ways over the
years, often going by the name "Holy Grail Layout" when there are two
additional columns. ‘order’ makes this trivial. For example, take
the following sketch of a page's code and desired layout:
<!DOCTYPE html> <header>...</header> <div id='main'> <article>...</article> <nav>...</nav> <aside>...</aside> </div> <footer>...</footer>
This layout can be easily achieved with flex layout:
#main { display: flex; }
#main > article { order: 2; min-width: 12em; flex:1; }
#main > nav { order: 1; width: 200px; }
#main > aside { order: 3; width: 200px; }
As an added bonus, the columns will all be equal-height by default, and the main content will be as wide as necessary to fill the screen. Additionally, this can then be combined with media queries to switch to an all-vertical layout on narrow screens:
@media all and (max-width: 600px) {
/* Too narrow to support three columns */
#main { flex-flow: column; }
#main > article, #main > nav, #main > aside {
/* Return them to document order */
order: 0; width: auto;
}
}
(Further use of multi-line flex containers to achieve even more intelligent wrapping left as an exercise for the reader.)
A flex container can be either single-line or multi-line, depending on the ‘flex-wrap’ property:
flex-wrap’ property. Every line contains at
least one flex item, unless the flex
container itself is completely empty.
This example shows four buttons that do not fit horizontally.
<style>
#flex {
display: flex;
flex-flow: row wrap;
width: 300px;
}
.item {
width: 80px;
}
</style>
<div id="flex">
<div class='item'>1</div>
<div class='item'>2</div>
<div class='item'>3</div>
<div class='item'>4</div>
</div>
Since the container is 300px wide, only three of the items fit onto a
single line. They take up 240px, with 60px left over of remaining space.
Because the ‘flex-flow’ property specifies a multi-line flex container (due to the ‘wrap’ keyword
appearing in its value), the flex container will create an additional
line to contain the last item.
Once content is broken into lines, each line is laid out independently;
flexible lengths and the ‘justify-content’ and ‘align-self’
properties only consider the items on a single line at a time.
When a flex container has multiple lines, the cross size of each line is the minimum size
necessary to contain the flex items on the
line (after aligment due to ‘align-self’), and the lines are aligned within
the flex container with the ‘align-content’ property. When a flex container
(even a multi-line one) has only one
line, the cross size of the line is the
cross size of the flex container, and
‘align-content’ has no effect. The main size of a line is always the same as the
main size of the flex container's content
box.
Here's the same example as the previous, except that the flex items
have all been given ‘flex: auto’. The first
line has 60px of remaining space, and all of the items have the same
flexibility, so each of the three items on that line will receives 20px
of extra width, ending up 100px wide. The remaining item is on a line of
its own and will stretch to the entire width of the line, or 300px.
flex: auto’.
The defining aspect of flex layout is the ability to make the flex items "flex", altering their width or
height to fill the available space. This is done with the ‘flex’ property. A flex
container distributes free space to its items proportional to their flex grow factor, or shrinks them to
prevent overflow proportional to their flex shrink factor.
flex’ Shorthand| Name: | flex |
|---|---|
| Value: | none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] |
| Initial: | see individual properties |
| Applies to: | flex items |
| Inherited: | see individual properties |
| Computed value: | see individual properties |
| Media: | visual |
| Animatable: | see individual properties |
| Canonical Order: | per grammar |
The ‘flex’ property
specifies the components of a flexible length: the flex grow factor and flex shrink factor, and the flex basis. When an element is a flex item, ‘flex’ is consulted instead of the main size property to determine the
main size of the element. If an element is
not a flex item, ‘flex’ has no effect.
flex-grow’>
This <number> component sets ‘flex-grow’ longhand and specifies the flex grow factor, 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. When omitted, it is
set to ‘1’.
flex-shrink’>
This <number> component sets ‘flex-shrink’ longhand and specifies the flex shrink factor, 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. When omitted, it
is set to ‘1’. The flex shrink factor is multiplied
by the flex basis when distributing
negative space.
flex-basis’>
This component, which takes the same values as the ‘width’ property, sets the ‘flex-basis’
longhand and specifies the flex basis: the initial main
size of the flex item, before
free space is distributed according to the flex factors. When omitted
from the ‘flex’
shorthand, its specified value is the length zero.
If the specified ‘flex-basis’ is ‘auto’, the used
flex basis is the value of the
element's main size property.
(This can itself be the keyword ‘auto’, which
sizes the element based on its contents.)
1’, ‘1’, and ‘2’, respectively.
none’
The keyword ‘none’ computes to ‘0 0
auto’.
The initial values of the ‘flex’ components are equivalent to ‘flex: 0 1 auto’.
Note that the initial values of ‘flex-grow’ and ‘flex-basis’
are different from their defaults when omitted in the ‘flex’ shorthand. This so
that the ‘flex’
shorthand can better accommodate the most common
cases.
A unitless zero that is not already preceded by two flex factors must be interpreted as a flex factor. To avoid misinterpretation or invalid declarations, authors must specify a zero <flex-basis> component with a unit or precede it by two flex factors.
flex’This section is informative.
The list below summarizes the effects of the most common ‘flex’ values:
flex: 0 auto’
flex: initial’
flex: 0 1 auto’. (This is
the initial 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. The alignment abilities or ‘auto’ margins can be
used to align flex items along the main
axis.
flex: auto’
flex: 1 1 auto’. 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’
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>’
flex: <positive-number> 1
0px’. 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.
min-width’ or ‘min-height’) to prevent them from shrinking too
small to fit their contents. This problem is especially common with
horizontal navigation or toolbars.
nav li { flex: 1; min-width: min-content; /* Don't overflow */}
Individual components of flexibility can be controlled by independent longhand properties.
Authors are encouraged to control flexibility using the
‘flex’ shorthand
rather than with component properties, as the shorthand correctly resets
any unspecified components to accommodate common
uses.
flex-grow’ property| Name: | flex-grow |
|---|---|
| Value: | <number> |
| Initial: | 0 |
| Applies to: | flex items |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | yes, except between ‘0’ and other values
|
| Canonical Order: | per grammar |
The ‘flex-grow’ property sets the flex grow factor. Negative numbers are
invalid.
flex-shrink’
property| Name: | flex-shrink |
|---|---|
| Value: | <number> |
| Initial: | 1 |
| Applies to: | flex items |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | yes, except between ‘0’ and other values
|
| Canonical Order: | per grammar |
The ‘flex-shrink’ property sets the flex shrink factor. Negative numbers
are invalid.
flex-basis’
property| Name: | flex-basis |
|---|---|
| Value: | <'width'> |
| Initial: | auto |
| Applies to: | flex items |
| Inherited: | no |
| Computed value: | as specified, with lengths made absolute |
| Percentages: | relative to the flex container's inner main size |
| Media: | visual |
| Animatable: | yes, insofar as ‘width’ is
animatable
|
| Canonical Order: | per grammar |
The ‘flex-basis’ property sets the flex basis. Negative lengths are invalid.
Except for ‘auto’, which retrieves the value of the main size property, ‘flex-basis’
is resolved the same way as ‘width’ in horizontal writing modes [CSS21]: percentage
values of ‘flex-basis’ are resolved against the flex
item's containing block, i.e. its flex container, and if that containing
block's size is indefinite, the result is undefined. Similarly, ‘flex-basis’
determines the size of the content box, unless otherwise specified such as
by ‘box-sizing’ [CSS3UI].
After a flex container's contents have finished their flexing and the dimensions of all flex items are finalized, they can then be aligned within the flex container.
The ‘margin’ properties can be used to
align items in a manner similar to, but more powerful than, what margins
can do in block layout. Flex items also
respect the alignment properties from the Box Alignment spec, which allow
easy keyword-based alignment of items in both the main axis and cross
axis. These properties make many common types of alignment
trivial, including some things that were very difficult in CSS 2.1, like
horizontal and vertical centering.
While the alignment properties are defined in the Box Alignment spec, Flexible Box Layout reproduces the definitions of the relevant ones here so as to not create a normative dependency that may slow down advancement of the spec. These properties apply only to flex layout until Box Alignment is finished and defines their effect for other layout modes.
auto’ marginsThis section is non-normative. The normative definition of how margins affect flex items is in the Flex Layout Algorithm section.
Auto margins on flex items have an effect very similar to auto margins in block flow:
0’.
justify-content’ and ‘align-self’, any
positive free space is distributed to auto margins in that dimension.
Note that, if free space is distributed to auto margins, the alignment properties will have no effect in that dimension because the margins will have stolen all the free space left over after flexing.
One use of ‘auto’ margins in the main axis
is to separate flex items into distinct "groups". The following example
shows how to use this to reproduce a common UI pattern - a single bar of
actions with some aligned on the left and others aligned on the right.
<style>
nav > ul {
display: flex;
}
nav > ul > li {
min-width: min-content;
/* Prevent items from getting too small for their content. */
}
nav > ul > #login {
margin-left: auto;
}
</style>
<nav>
<ul>
<li><a href=/about>About</a>
<li><a href=/projects>Projects</a>
<li><a href=/interact>Interact</a>
<li id='login'><a href=/login>Login</a>
</ul>
</nav>
The figure below illustrates the difference in cross-axis alignment in
overflow situations between using ‘auto’ margins and using the alignment properties. align-self’. If this
column flex container was placed against the left edge of the page, the
margin behavior would be more desirable, as the long item would be fully
readable. In other circumstances, the true centering behavior might be
better.
justify-content’ property| Name: | justify-content |
|---|---|
| Value: | flex-start | flex-end | center | space-between | space-around |
| Initial: | flex-start |
| Applies to: | flex containers |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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.
flex-start’
flex-end’
center’
space-between’
flex-start’. Otherwise, the main-start margin edge of the first flex item on the line is placed flush with
the main-start edge of the line, the main-end margin edge of the last flex item on the line is placed flush with
the main-end edge of the line, and the
remaining flex items on the line are
distributed so that the empty space between any two adjacent items is the
same.
space-around’
center’.
Otherwise, the flex items on the line are
distributed such that the empty space between any two adjacent flex items on the line is the same, and the
empty space before the first and after the last flex items on the line are half the size of
the other empty spaces.
An illustration of the five ‘justify-content’ keywords and their effects
on a flex container with three colored items.
align-items’ and ‘align-self’
properties| Name: | align-items |
|---|---|
| Value: | flex-start | flex-end | center | baseline | stretch |
| Initial: | stretch |
| Applies to: | flex containers |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
| Name: | align-self |
|---|---|
| Value: | auto | flex-start | flex-end | center | baseline | stretch |
| Initial: | auto |
| Applies to: | flex items |
| Inherited: | no |
| Computed value: | ‘auto’ computes to parent's ‘align-items’;
otherwise as specified
|
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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, including anonymous flex items. ‘align-self’ allows this default alignment to
be overridden for individual flex items.
(For anonymous flex items, ‘align-self’ always matches the value of ‘align-items’ on
their associated flex container.)
If either of the flex item's cross-axis
margins are ‘auto’, ‘align-self’ has no
effect.
A value of ‘auto’ for ‘align-self’ computes to the value of ‘align-items’ on the
element's parent, or ‘stretch’ if the element has no parent. The
alignments are defined as:
flex-start’
flex-end’
center’
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’
If the cross size property
of the flex item computes to ‘auto’, its used value is the length necessary to make
the cross size of the item's margin box
as close to the same size as the line as possible, while still
respecting the constraints imposed by ‘min/max-width/height’.
Note that if the flex container's height is constrained this value may cause the contents of the flex item to overflow the item.
The cross-start margin edge of the flex item is placed flush with the cross-start edge of the line.
An illustration of the five ‘align-items’
keywords and their effects on a flex container with four colored items.
align-content’ property| Name: | align-content |
|---|---|
| Value: | flex-start | flex-end | center | space-between | space-around | stretch |
| Initial: | stretch |
| Applies to: | multi-line flex containers |
| Inherited: | no |
| Computed value: | specified value |
| Media: | visual |
| Animatable: | no |
| Canonical Order: | per grammar |
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. Note, this property has no effect when the
flex container has only a single line. Values have the following meanings:
flex-start’
flex-end’
center’
space-between’
flex-start’. Otherwise, the cross-start edge of the first line in the
flex container is placed flush with the cross-start content edge of the flex
container, the cross-end edge of the last
line in the flex container is placed flush with the cross-end content edge of the flex
container, and the remaining lines in the flex container are distributed
so that the empty space between any two adjacent lines is the same.
space-around’
center’. Otherwise, the lines in the flex
container are distributed such that the empty space between any two
adjacent lines is the same, and the empty space before the first and
after the last lines in the flex container are half the size of the other
empty spaces.
stretch’
flex-start’. Otherwise, the free-space is split
equally between all of the lines, increasing their cross size.
Note: 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.
An illustration of the ‘align-content’ keywords and their effects on
a multi-line flex container.
The baselines of a flex container are determined as follows (after
reordering with ‘order’):
When calculating the baseline according to the above rules, if the box
contributing a baseline has an ‘overflow’
value that allows scrolling, the box must be treated as being in its
initial scroll position for the purpose of determining its baseline.
When determining the baseline of a table cell, a flex container provides a baseline just as a line box or table-row does. [CSS21]
CSS 2.1 did not define the baseline of block or table boxes. It is expected that they will be defined consistent with those of table cells, as follows:
block’
list-item’
The inline-axis baseline of a block is the baseline of the first
in-flow line box in the block, or the first in-flow block-level child
in the block that has a baseline, whichever comes first. If there is no
such line box or child, then the block has no baseline. For the
purposes of finding a baseline, in-flow boxes with a scrolling
mechanisms (see the ‘overflow’
property) must be considered as if scrolled to their origin position.
A block has no block-axis baseline.
table’
The inline-axis baseline of a table box is the baseline of its first row. However, when calculating the baseline of an inline-block, table boxes must be skipped.
The block-axis baseline of a table is undefined.
This section contains normative algorithms detailing the exact layout behavior of a flex container and its contents. The algorithms here are written to optimize readability and theoretical simplicity, and may not necessarily be the most efficient. Implementations may use whatever actual algorithms they wish, but must produce the same results as the algorithms described here.
This section is mainly intended for implementors. Authors writing web pages should generally be served well by the individual property descriptions, and do not need to read this section unless they have a deep-seated urge to understand arcane details of CSS layout.
For the purposes of these definitions, a definite size is one that can be
determined without measuring content, i.e. is a <length>, a
size of the initial containing block, or a <percentage> that
is resolved against a definite size. If a single-line flex container has a definite cross
size, any flex items with ‘align-self: stretch’ must also be treated as having a
definite cross size. An indefinite size is one that is
not definite.
The following sections define the algorithm for laying out a flex container and its contents.
order’. The
elements with the lowest (most negative) ‘order’ values are first in the ordering. If
multiple elements share an ‘order’ value, they're ordered by document
order. This affects the order in which the elements generate boxes in the
box-tree, and how the rest of this algorithm deals with the generated
flex items.
auto’ or depends
on its available size, and the flex container is being sized under a
min-content or max-content constraint (e.g. when performing automatic
table layout [CSS21]), size the item under that
constraint. The flex base size is
the item's resulting main size.
align-self: stretch’, the flex basis and
cross size are both ‘auto’ , and the flex
container is single-line and has a definite cross size, the flex base size is computed from the
flex container's inner cross size (clamped to the flex item’s min and max cross size) and the flex item’s intrinsic aspect ratio.
This substep needs review, see thread at http://lists.w3.org/Archives/Public/www-style/2012Oct/0781.html.
auto’
or depends on its available size, the available main size is infinite,
and the flex item's inline axis is parallel to the main axis, lay the
item out using the
rules for a box in an orthogonal flow [CSS3-WRITING-MODES].
The flex base size is the item's
max-content main size.
auto’ as ‘max-content’.
The flex base size is the item's
resulting main size.
auto’
margins on flex items are treated as ‘0’.
page-break-before/after’ [CSS21] or the CSS3 ‘break-before/after’ [CSS3-BREAK] properties
specify a fragmentation break.
For this step, the size of a flex item is its outer hypothetical main size.
Repeat until all flex items have been collected into flex lines.
Note that the "collect as many" line will collect zero-sized flex items onto the end of the previous line even if the last non-zero item exactly "filled up" the line.
auto’ as ‘fit-content’.
If the flex container has only a single line (even if it's a multi-line flex container) and has a definite cross size, the cross size of the flex line is the flex container's inner cross size.
Otherwise, for each flex line:
align-self’ is ‘baseline’, and
whose cross-axis margins are both non-‘auto’. Find the largest of the distances between
each item's baseline and its hypothetical outer cross-start edge, and
the largest of the distances between each item's baseline and its
hypothetical outer cross-end edge, and sum these two values.
align-content:
stretch’. If the flex container has a definite cross size, ‘align-content’ is
‘stretch’, and the sum of the flex lines' cross
sizes is less than the flex container's inner cross size, increase the
cross size of each flex line by equal amounts such that the sum of their
cross sizes exactly equals the flex container's inner cross size.
visibility:collapse’ items. If any flex items
have ‘visibility: collapse’, note the cross
size of the line they're in as the item's strut
size, and restart layout from the beginning.
In this second layout round, when collecting items into lines, treat the
collapsed items as having zero main size. For the rest of the algorithm
following that step, ignore the collapsed items entirely (as if they
were ‘display:none’) except that after calculating the cross size of the lines, if
any line's cross size is less than the largest strut size among all the collapsed
items in the line, set its cross size to that strut size.
Skip this step in the second layout round.
align-self:
stretch’, its computed cross size property is ‘auto’, and neither of its cross-axis margins are
‘auto’, the used outer cross size is the used
cross size of its flex line, clamped according to the item's min and max
cross size properties. Otherwise, the used cross size is the item's hypothetical cross size.
Note that this step does not affect the main size of the flex item, even if it has an intrinsic aspect ratio.
auto’, distribute
the free space equally among these margins. Otherwise, set all ‘auto’ margins to zero.
justify-content’.
auto’ margins. If a flex item has ‘auto’ cross-axis margins:
auto’ margins as zero) is less than the cross size
of its flex line, distribute the difference in those sizes equally to
the ‘auto’ margins.
auto’,
set it to zero; set the opposite margin so that the outer cross size of
the item equals the cross size of its flex line.
align-self’, if neither of the item's
cross-axis margins are ‘auto’.
align-content’.
To resolve the flexible lengths of the items within a flex line:
clamped size - unclamped size).
If the total violation is:
The max-content main size of a flex container is the sum of the flex container's items' max-content contributions. The min-content main size of a single-line flex container is the sum of the flex container's items' min-content contributions; for a multi-line container, it is the largest of those contributions.
The min-content cross size and max-content cross size of a flex container are the cross size of the flex container after performing layout into the given available main-axis space and infinite available cross-axis space.
The main-size min-content/max-content contribution of a flex item is its outer hypothetical main size when sized under a min-content/max-content constraint (respectively).
See [CSS3-SIZING] for a definition of the terms in this section.
Flex containers can break across pages between items, between lines of
items (in multi-line mode), and inside
items. The ‘break-*’ properties apply to flex
containers as normal for block-level or inline-level boxes. This section
defines how they apply to flex items and elements inside flex items.
The following breaking rules refer to the fragmentation container as the “page”. The same rules apply to any other fragmenters. (Substitute “page” with the appropriate fragmenter type as needed.) See the CSS3 Fragmentation Module [CSS3-BREAK]. For readability, in this section the terms "row" and "column" refer to the relative orientation of the flex container with respect to the block flow direction of the fragmentation context, rather than to that of the flex container itself.
The exact layout of a fragmented flex container is not defined in this level of Flexible Box Layout. However, breaks inside a flex container are subject to the following rules:
break-before’ and ‘break-after’ properties on flex items are
propagated to the flex line. The ‘break-before’ property on the first line and the
‘break-after’ property on the last line
are propagated to the flex container.
break-before’ property on the first item and the
‘break-after’ property on the last item
are propagated to the flex container. Forced breaks on other items are
applied to the item itself.
This informative section presents a possible fragmentation algorithm for flex containers. Implementors are encouraged to improve on this algorithm and provide feedback to the CSS Working Group.
This algorithm assumes that pagination always proceeds only in the forward direction; therefore, in the algorithms below, alignment is mostly ignored prior to pagination. Advanced layout engines may be able to honor alignment across fragments.
It is the intent of this algorithm that column-direction
single-line flex containers paginate
very similarly to block flow. As a test of the intent, a flex container
with ‘justify-content:start’ and no flexible
items should paginate identically to a block with in-flow children with
same content, same used size and same used margins.
If a flex item does not entirely fit on a single page, it will not be paginated in multi-line column flex containers.
align-self’ other than ‘start’ or ‘baseline’ as ‘start’.
Any flex items that fit entirely into previous fragments still take up space in the main axis in later fragments.
align-self’ and
‘align-content’ as being ‘start’ for all item fragments and lines.
align-self’ value
into the combined cross size of all the flex container fragments,
would fit entirely within a single flex container fragment, it may be
shifted into that fragment and aligned appropriately.
If a line doesn't fit on the page, and the line is not at the top of the page, move the line to the next page and restart the flex layout algorithm entirely, using only the items in and following this line.
If a flex item itself causes a forced break, rerun the flex layout algorithm from Main Sizing Determination through Main-Axis Alignment, using only the items on this and following lines, but with the item causing the break automatically starting a new line in the line breaking step, then continue with this step. Forced breaks within flex items are ignored.
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples in this specification are introduced with the words “for
example” or are set apart from the normative text with
class="example", like this:
This is an example of an informative example.
Informative notes begin with the word “Note” and are set apart from
the normative text with class="note", like this:
Note, this is an informative note.
Conformance to CSS Flexible Box Layout Module is defined for three conformance classes:
A style sheet is conformant to CSS Flexible Box Layout Module if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.
A renderer is conformant to CSS Flexible Box Layout Module if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by CSS Flexible Box Layout Module by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)
An authoring tool is conformant to CSS Flexible Box Layout Module if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.
So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.
To avoid clashes with future CSS features, the CSS2.1 specification reserves a prefixed syntax for proprietary and experimental extensions to CSS.
Prior to a specification reaching the Candidate Recommendation stage in the W3C process, all implementations of a CSS feature are considered experimental. The CSS Working Group recommends that implementations use a vendor-prefixed syntax for such features, including those in W3C Working Drafts. This avoids incompatibilities with future changes in the draft.
Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementers should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.
To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.
Further information on submitting testcases and implementation reports can be found from on the CSS Working Group's website at http://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.
For this specification to be advanced to Proposed Recommendation, there must be at least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products, there is no requirement that all features be implemented by a single product. For the purposes of this criterion, we define the following terms:
The specification will remain Candidate Recommendation for at least six months.
Thanks for feedback and contributions to Erik Anderson, Tony Chang, Phil Cupp, Arron Eicholz, James Elmore, Andrew Fedoniouk, Brian Heuston, Shinichiro Hamaji, Daniel Holbert, Ben Horst, John Jansen, Brad Kemper, Kang-hao Lu, Markus Mielke, Robert O'Callahan, Christoph Päper, Ning Rogers, Peter Salas, Morten Stenshorne, Christian Stockwell, Ojan Vafai, Eugene Veselov, Boris Zbarsky.
The following significant changes were made since the 18 September 2012 Candidate Recommendation:
min-width’/‘min-height’ back to being ‘0’ (not ‘auto’).
The following significant clarifications were also made:
float’ still makes
the children of a flex container turn into block-level elements.
overflow’ applies to
flex containers.
::first-line’ and ‘::first-letter’ pseudo-elements do not apply to flex
containers (because they are not block containers).
stretch’ checks for the computed value of
the cross-size property being ‘auto’, which
means that percentage cross-sizes that behave as ‘auto’ (because they don't resolve against definite
sizes) aren't stretched.
order’-modified document order is used
instead of raw document order when painting. (This was already stated in
the ‘order’ section,
but not in the section explicitly about painting order.)
A Disposition of Candidate Recommendation Comments is available.
| Property | Values | Initial | Applies to | Inh. | Percentages | Media |
|---|---|---|---|---|---|---|
| align-content | flex-start | flex-end | center | space-between | space-around | stretch | stretch | multi-line flex containers | no | visual | |
| align-items | flex-start | flex-end | center | baseline | stretch | stretch | flex containers | no | visual | |
| align-self | auto | flex-start | flex-end | center | baseline | stretch | auto | flex items | no | visual | |
| flex | none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] | see individual properties | flex items | see individual properties | visual | |
| flex-basis | <'width'> | auto | flex items | no | relative to the flex container's inner main size | visual |
| flex-direction | row | row-reverse | column | column-reverse | row | flex containers | no | visual | |
| flex-flow | <‘flex-direction’> || <‘flex-wrap’> | see individual properties | flex containers | see individual properties | visual | |
| flex-grow | <number> | 0 | flex items | no | visual | |
| flex-shrink | <number> | 1 | flex items | no | visual | |
| flex-wrap | nowrap | wrap | wrap-reverse | nowrap | flex containers | no | visual | |
| justify-content | flex-start | flex-end | center | space-between | space-around | flex-start | flex containers | no | visual | |
| order | <integer> | 0 | flex items and absolutely-positioned flex container children | no | visual |
baseline’, 8.3.
center’, 8.3., 8.4., 8.2.
column’, 5.1.
column-reverse’, 5.1.
flex’, 3.
flex-end’, 8.4., 8.3., 8.2.
flex-start’, 8.4., 8.3.,
8.2.
inline-flex’, 3.
none’, 7.1.
nowrap’, 5.2.
row’, 5.1.
row-reverse’, 5.1.
space-around’, 8.4., 8.2.
space-between’, 8.4., 8.2.
stretch’, 8.4., 8.3.
wrap’, 5.2.
wrap-reverse’, 5.2.