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.
A Candidate Recommendation is a document that has been widely reviewed and is ready for implementation. W3C encourages everybody to implement this specification and return comments to the (archived ) public mailing list www-style@w3.org (see instructions ). When sending e-mail, please put the text “css3-flexbox” in the subject, preferably like this: “[css3-flexbox] _…summary of comment…_”
Publication as a Candidate Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
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.
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.
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:
This is the best computer money can buy, if you don't have much money.
Only capable of printing ASCII art.
An example rendering of the code above.
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.
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]
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:
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.
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.
Note: Descendants that are positioned outside a flex item still participate in any stacking context established by the flex item.
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.
…
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.)
4.5. Implied Minimum Size of Flex Items To provide a more reasonable default minimum size for flex items, this specification introduces a new ‘auto’ value as the initial value of the ‘min-width
’ and ‘min-height
’ properties defined in CSS 2.1. [CSS21]
Name:
min-width, min-height
New value :
auto
New Initial Value:
auto
New Computed Value:
the percentage as specified or the absolute length or a keyword
auto
When used as the value of a flex item's min main size property, this keyword indicates a minimum of the min-content size, to help ensure that the item is large enough to fit its contents.
It is intended that this will compute to the ‘min-content
’ keyword when the specification defining it (Writing Modes Appendix D ) is sufficiently mature.
Otherwise, this keyword computes to ‘0
’ (unless otherwise defined by a future specification).
Note that while a content-based minimum size is often appropriate, and helps prevent content from overlapping or spilling outside its container, in some cases it is not:
In particular, if flex sizing is being used for a major content area of a document, it is better to set an explicit font-relative minimum width such as ‘min-width: 12em
’. A content-based minimum width could result in a large table or large image stretching the size of the entire content area into an overflow zone, and thereby making lines of text gratuitously long and hard to read.
Note also, when content-based sizing is used on an item with large amounts of content, the layout engine must traverse all of this content before finding its minimum size, whereas if the author sets an explicit minimum, this is not necessary. (For items with small amounts of content, however, this traversal is trivial and therefore not a performance concern.)
5. Ordering and Orientation 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.
5.1. Flex Flow Direction: the ‘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
’
The flex container's main axis has the same orientation as the inline axis of the current writing mode . The main-start and main-end directions are equivalent to the start and end directions, respectively, of the current writing mode .
‘row-reverse
’
Same as ‘row ’, except the main-start and main-end directions are swapped.
‘column
’
The flex container's main axis has the same orientation as the block axis of the current writing mode . The main-start and main-end directions are equivalent to the before /head and after /foot directions, respectively, of the current writing mode .
‘column-reverse
’
Same as ‘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.
5.2. Flex Line Wrapping: the ‘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
’
The flex container is single-line . The cross-start direction is equivalent to either the start or_before_/head direction of the current writing mode , whichever is in the cross axis , and the cross-end direction is the opposite direction of cross-start .
‘wrap
’
The flex container is multi-line . The cross-start direction is equivalent to either the start or_before_/head direction of the current writing mode , whichever is in the cross axis , and the cross-end direction is the opposite direction of cross-start .
‘wrap-reverse
’
Same as ‘wrap ’, except the cross-start and cross-end directions are swapped.
5.3. Flex Direction and Wrap: the ‘flex-flow ’ shorthand
Name:
flex-flow
Value :
<‘flex-direction ’> |
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:
Note that the ‘flex-flow ’ directions are writing-mode sensitive. In vertical Japanese, for example, a ‘row ’ flexbox lays out its contents from top to bottom, as seen in this example:
English
Japanese
flex-flow: row wrap;writing-mode: horizontal-tb;
flex-flow: row wrap;writing-mode: vertical-rl;
5.4. Display Order: the ‘order ’ propertyFlex 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 :
Initial:
0
Applies to:
flex items
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 > .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 .
5.4.1. Reordering and Accessibility 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:
This layout can be easily achieved with flex layout:
#main { display: flex; }
#main > article { flex:1; order: 2; }
#main > nav { width: 200px; order: 1; }
#main > aside { width: 200px; order: 3; }
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.)
6. Flex Lines A flex container can be either single-line or multi-line , depending on the ‘flex-wrap ’ property:
A single-line flex container lays out all of its children in a single line, even if that would cause its contents to overflow.
A multi-line flex container breaks its flex items across multiple lines, similar to how text is broken onto a new line when it gets too wide to fit on the existing line. When additional lines are created, they are stacked in the flex container along the cross axis according to the ‘flex-wrap ’ property. Every line contains at least one flex item , unless the flex container itself is completely empty.
This example shows four buttons that do not fit horizontally.
The figure below illustrates the difference in cross-axis alignment in overflow situations between using ‘auto’ margins and using the alignment properties .
About
Authoritarianism
Blog
About
Authoritarianism
Blog
The items in the figure on the left are centered with margins, while those in the figure on the right are centered with ‘align-self ’. If this column flexbox 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.
8.2. Axis Alignment: the ‘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 items are packed toward the start of the line. The main-start margin edge of the first flex item on the line is placed flush with the main-start edge of the line, and each subsequent flex item is placed flush with the preceding item.
‘flex-end
’
Flex items are packed toward the end of the line. The main-end margin edge of the last flex item is placed flush with the main-end edge of the line, and each preceding flex item is placed flush with the subsequent item.
‘center
’
Flex items are packed toward the center of the line. The flex items on the line are placed flush with each other and aligned in the center of the line, with equal amounts of empty space between the main-start edge of the line and the first item on the line and between the main-end edge of the line and the last item on the line. (If the leftover free-space is negative, the flex items will overflow equally in both directions.)
‘space-between
’
Flex items are evenly distributed in the line. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to ‘flex-start’ . Otherwise, the 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
’
Flex items are evenly distributed in the line, with half-size spaces on either end. If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to ‘center’ . Otherwise, the flex items on the line are distributed such that the 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.
8.3. Cross-axis Alignment: the ‘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
’
The cross-start margin edge of theflex item is placed flush with the cross-start edge of the line.
‘flex-end
’
The cross-end margin edge of the flex item is placed flush with the cross-end edge of the line.
‘center
’
The flex item 's margin box is centered in the cross axis within the line. (If the cross size of the flex line is less than that of the flex item , it will overflow equally in both directions.)
‘baseline
’
If the flex item 's inline axis is the same as the cross axis , this value is identical to ‘flex-start’ .
Otherwise, it participates in baseline alignment: all participating flex items on the line are aligned such that their baselines align, and the item with the largest distance between its baseline and its cross-start margin edge is placed flush against the cross-start edge of the line.
‘stretch
’
If the cross size property of the flex item is ‘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 theflex 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.
8.4. Packing Flex Lines: the ‘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 flexbox has only a single line. Values have the following meanings:
‘flex-start
’
Lines are packed toward the start of the flex container. The cross-start edge of the first line in the flex container is placed flush with the cross-start edge of the flex container, and each subsequent line is placed flush with the preceding line.
‘flex-end
’
Lines are packed toward the end of the flex container. The cross-end edge of the last line is placed flush with the cross-end edge of the flex container, and each preceding line is placed flush with the subsequent line.
‘center
’
Lines are packed toward the center of the flex container. The lines in the flex container are placed flush with each other and aligned in the center of the flex container, with equal amounts of empty space between the cross-start content edge of the flex container and the first line in the flex container, and between thecross-end content edge of the flex container and the last line in the flex container. (If the leftover free-space is negative, the lines will overflow equally in both directions.)
‘space-between
’
Lines are evenly distributed in the flex container. If the leftover free-space is negative this value is identical to ‘flex-start’ . Otherwise, the cross-start edge of the first line in the flex container is placed 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
’
Lines are evenly distributed in the flex container, with half-size spaces on either end. If the leftover free-space is negative this value is identical to ‘center’ . Otherwise, the lines in the flex container are distributed such that the 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
’
Lines stretch to take up the remaining space. If the leftover free-space is negative, this value is identical to ‘flex-start’ . Otherwise, the free-space is split equally between all of the lines, increasing their cross size.
Note: 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.
8.5. Flex Baselines The baselines of a flex container are determined as follows (after reordering with ‘order ’):
main-axis baseline
If any of the flex items on the flex container's first line participate in baseline alignment , the flex container's main-axis baseline is the baseline of those flex items .
Otherwise, if the flex container has at least one flex item , and its first flex item has a baseline parallel to the flex container's main axis , the flex container's main-axis baseline is that baseline.
Otherwise, the flex container's main-axis baseline is synthesized from the first item's content box, or, failing that, from the flex container's content box.
cross-axis baseline
If the flex container has at least one flex item , and its first flex item has a baseline parallel to the flex container's cross axis , the flex container's cross-axis baseline is that baseline.
Otherwise, the flex container's cross-axis baseline is synthesized from the first item's content box, or, failing that, from the flex container's content box.
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.
9. Flex Layout Algorithm 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 , a size of the initial containing block, or a that is resolved against a definite 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.
9.1. Initial Setup
Generate anonymous flex items as described in the Flex Items section.
Re-order the flex items according to their ‘order ’. The items with the lowest (most negative) ‘order ’ values are first in the ordering. If multiple items share a ‘order ’ value, they're ordered by document order. This affects the order in which the flex items generate boxes in the box-tree, and how the rest of this algorithm deals with the items.
9.2. Line Length Determination
Determine the available main and cross space for the flex items. For each dimension, if that dimension of the flex container is a definite size , use that; otherwise, subtract the flex container's margin, border, and padding from the space available to the flex container in that dimension and use that value. This might result in an infinite value.
Determine the flex base size and hypothetical main size of each item:
If the item has a definite flex basis, that's the flex base size .
If the flex basis is ‘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.
Otherwise, if the flex basis is ‘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.
Otherwise, lay out the item into the available space using its flex basis in place of its main size, and treating ‘auto
’ as ‘max-content
’. The flex base size is the item's resulting main size. The hypothetical main size is the item's flex base size clamped according to its min and max main size properties.
Determine the main size of the flex container using its main size property . In this calculation, the min content main size of the flex container is the maximum of the flex container's items'min-content size contributions , and the max content main size of the flex container is the sum of the flex container's items'max-content size contributions . The min-content/max-content main size contribution of an item is its outer hypothetical main size when sized under a min-content/max-content constraint (respectively). For this computation, ‘auto
’ margins on flex items are treated as ‘0
’.
9.3. Main Size Determination
Collect flex items into flex lines:
If the flex container is single-line, collect all the flex items into a single flex line.
Otherwise, starting from the first uncollected item, collect as many consecutive flex items as will fit or until a forced break is encountered (but collect at least one) into the flex container's inner main size into a flex line. A break is forced wherever the CSS2.1 ‘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 items with zero main size will never start a line unless they're the very first items in the flex container, or they're preceded by a forced break. The "collect as many" line will collect them onto the end of the previous line even if the last non-zero item exactly "filled up" the line.
Resolve the flexible lengths of all the flex items to find their used main size (see section 9.7.).
9.4. Cross size determination
Determine the hypothetical cross size of each item by performing layout with the used main size and the available space, treating ‘auto
’ as ‘fit-content
’.
Calculate the cross size of each flex line. If the flex container has only a single line (even if it's a multi-line flex container), the cross size of the flex line is the flex container's inner cross size. Otherwise, for each flex line:
Collect all the flex items whose inline-axis is parallel to the main-axis, whose ‘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.
Among all the items not collected by the previous step, find the largest outer hypothetical cross size .
The used cross-size of the flex line is the larger of the numbers found in the previous two steps.
Handle ‘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.
Collapse ‘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.
Determine the used cross size of each flex item. If a flex item has ‘align-self: stretch
’, its 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 .
9.5. Main-Axis Alignment
Distribute any remaining free space. For each flex line:
If the remaining free space is positive and at least one main-axis margin on this line is ‘auto
’, distribute the free space equally among these margins. Otherwise, set all ‘auto
’ margins to zero.
Align the items along the main-axis per ‘justify-content ’.
9.6. Cross-Axis Alignment
Resolve cross-axis ‘auto
’ margins. If a flex item has ‘auto
’ cross-axis margins:
If its outer cross size (treating those ‘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.
Otherwise, if the start or head margin (whichever is in the cross axis) is ‘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 all flex items along the cross-axis per ‘align-self ’, if neither of the item's cross-axis margins are ‘auto
’.
Determine the flex container's used cross size:
If the cross size property is a definite size, use that.
Otherwise, use the sum of the flex lines' cross sizes.
Align all flex lines per ‘align-content ’.
9.7. Resolving Flexible Lengths To resolve the flexible lengths of the items within a flex line:
Determine the used flex factor. Sum the outer hypothetical main sizes of all items on the line. If the sum is less than the flex container's inner main size, use the flex grow factor for the rest of this algorithm; otherwise, use the flex shrink factor .
Size inflexible items. For any items that have a flex factor of zero, set their used main size to their hypothetical main size .
Check that you can distribute any space. If all the flex items on the line are either frozen or have a flex factor of zero, exit the algorithm.
Calculate free space. Sum the outer flex base sizes of all items on the line, and subtract this from the flex container's inner main size. This is the free space.
Distribute free space proportional to the flex factors. If the sign of the free space is positive and the algorithm is using the flex grow factor , or if the sign of the free space is negative and the algorithm is using the flex shrink factor , distribute the free space to each flexible item's main size in proportion to the item's flex factor: If the free space is positive Find the ratio of the item's flex grow factor to the sum of the flex grow factors of all items on the line. Set the item's main size to its flex base size plus a fraction of the free space proportional to the ratio. If the free space is negative For every item on the line, multiply its flex shrink factor by its outerflex base size , and note this as its scaled flex shrink factor. Find the ratio of the item's scaled flex shrink factor to the sum of the scaled flex shrink factors of all items on the line. Set the item's main size to its flex base size minus a fraction of the absolute value of the free space proportional to the ratio. Note this may result in a negative inner main size; it will be corrected in the next step.
Fix min/max violations. Clamp each item's main size by its min and max main size properties. If the item's main size was made smaller by this, it's a max violation. If the item's main size was made larger by this, it's a min violation.
The total violation is the sum of the adjustments from the previous step (clamped size - unclamped size
). If the total violation is: Zero Exit the algorithm. Positive Freeze all the items with min violations, reset all other items to their size upon entering this algorithm, and return to step 2 of this algorithm. Negative Freeze all the items with max violations, reset all other items to their size upon entering this algorithm, and return to step 2 of this algorithm.
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:
In a row flex container, the ‘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.
In a column flex container, the ‘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.
A forced break inside a flex item effectively increases the size of its contents; it does not trigger a forced break inside sibling items.
In a row flex container, Class 1 break opportunities occur between sibling flex lines, and Class 3 break opportunities occur between the first/last flex line and the flex container's content edges. In a column flex container, Class 1 break opportunities occur between sibling flex items, and Class 3 break opportunities occur between the first/last flex items on a line and the flex container's content edges. [CSS3-BREAK]
When a flex container is continued after a break, the space available to its flex items (in the block flow direction of the fragmentation context) is reduced by the space consumed by flex container fragments on previous pages. The space consumed by a flex container fragment is the size of its content box on that page. If as a result of this adjustment the available space becomes negative, it is set to zero.
If the first fragment of the flex container is not at the top of the page, and some of its flex items don't fit in the remaining space on the page, the entire fragment is moved to the next page.
When a multi-line colum flex container breaks, each fragment has its own "stack" of flex lines, just like each fragment of a multi-column element has its own row of column boxes.
Aside from the rearrangement of items imposed by the previous point, UAs should attempt to minimize distortation of the flex container with respect to unfragmented flow.
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.
Single-line column flex container
Run the flex layout algorithm (without regards to pagination) through Cross Sizing Determination .
Lay out as many consecutive flex items or item fragments as possible (but at least one or a fragment thereof), starting from the first, until there is no more room on the page or a forced break is encountered.
If the previous step ran out of room and the free space is positive, the UA may reduce the distributed free space on this page (down to, but not past, zero) in order to make room for the next unbreakable flex item or fragment. Otherwise, the item or fragment that does not fit is pushed to the next page. The UA should pull up if more than 50% of the fragment would have fit in the remaining space and should push otherwise.
If there are any flex items or fragments not laid out by the previous steps, rerun the flex layout algorithm from Line Length Determination through Cross Sizing Determination with the next page's size and all the contents (including those already laid out), and return to the previous step, but starting from the first item or fragment not already laid out.
For each fragment of the flex container, continue the flex layout algorithm from Main-Axis Alignment to its finish.
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.
Multi-line column flex container
Run the flex layout algorithm with regards to pagination (limiting the flex container's maximum line length to the space left on the page) through Cross Sizing Determination .
Lay out as many flex lines as possible (but at least one) until there is no more room in the flex container in the cross dimension or a forced break is encountered:
Lay out as many consecutive flex items as possible (but at least one), starting from the first, until there is no more room on the page or a forced break is encountered. Forced breaks within flex items are ignored.
If this is the first flex container fragment, this line contains only a single flex item that is larger than the space left on the page, and the flex container is not at the top of the page already, move the flex container to the next page and restart flex container layout entirely.
If there are any flex items not laid out by the first step, rerun the flex layout algorithm from Main Sizing Determination through Cross Sizing Determination using only the items not laid out on a previous line, and return to the previous step, starting from the first item not already laid out.
If there are any flex items not laid out by the previous step, rerun the flex layout algorithm from Line Sizing Determination through Cross Sizing Determination with the next page's size and only the items not already laid out, and return to the previous step, but starting from the first item not already laid out.
For each fragment of the flex container, continue the flex layout algorithm from Main-Axis Alignment to its finish.
If a flex item does not entirely fit on a single page, it will not be paginated in multi-line column flex containers.
Single-line row flex container
Run the entire flex layout algorithm (without regards to pagination), except treat any ‘align-self ’ other than ‘start
’ or ‘baseline ’ as ‘start
’.
If an unbreakable item doesn't fit within the space left on the page, and the flex container is not at the top of the page, move the flex container to the next page and restart flex container layout entirely.
For each item, lay out as much of its contents as will fit in the space left on the page, and fragment the remaining content onto the next page, rerunning the flex layout algorithm from Line Length Determination through Main-Axis Alignment into the new page size using all the contents (including items completed on previous pages). Any flex items that fit entirely into previous fragments still take up space in the main axis in later fragments.
For each fragment of the flex container, rerun the flex layout algorithm from Cross-Axis Alignment to its finish. For all fragments besides the first, treat ‘align-self ’ and ‘align-content ’ as being ‘start
’ for all item fragments and lines.
If any item, when aligned according to its original ‘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.
Multi-line row flex container
Run the flex layout algorithm (without regards to pagination), through Cross Sizing Determination .
Lay out as many flex lines as possible (but at least one), starting from the first, until there is no more room on the page or a forced break is encountered. 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.
If there are any flex items not laid out by the previous step, rerun the flex layout algorithm from Line Length Determination through Main-Axis Alignment with the next page's size and only the items not already laid out. Return to the previous step, but starting from the first line not already laid out.
For each fragment of the flex container, continue the flex layout algorithm from Cross Axis Alignment to its finish.
11.1. Document conventionsConformance 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 withclass="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:
style sheet
A CSS style sheet .
renderer
A UA that interprets the semantics of a style sheet and renders documents that use them.
A UA that writes a style sheet.
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.
11.3. Partial implementationsSo 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.
11.4. Experimental implementationsTo 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.
11.5. Non-experimental implementationsOnce 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.
11.6. CR exit criteria 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:
independent
each implementation must be developed by a different party and cannot share, reuse, or derive from code used by another qualifying implementation. Sections of code that have no bearing on the implementation of this specification are exempt from this requirement.
interoperable
passing the respective test case(s) in the official CSS test suite, or, if the implementation is not a Web browser, an equivalent test. Every relevant test in the test suite should have an equivalent test created if such a user agent (UA) is to be used to claim interoperability. In addition if such a UA is to be used to claim interoperability, then there must one or more additional UAs which can also pass those equivalent tests in the same way for the purpose of interoperability. The equivalent tests must be made publicly available for the purposes of peer review.
implementation
a user agent which:
implements the specification.
is available to the general public. The implementation may be a shipping product or other publicly available version (i.e., beta version, preview release, or “nightly build”). Non-shipping product releases must have implemented the feature(s) for a period of at least one month in order to demonstrate stability.
is not experimental (i.e., a version specifically designed to pass the test suite and is not intended for normal usage going forward).
The specification will remain Candidate Recommendation for at least six months.
AcknowledgmentsThanks 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.
References Normative references[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-CSS2-20110607
[CSS3-BREAK]
Rossen Atanassov; Elika J. Etemad. CSS Fragmentation Module Level 3. 23 August 2012. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2012/WD-css3-break-20120823/
[CSS3-WRITING-MODES]
Elika J. Etemad; Koji Ishii. CSS Writing Modes Module Level 3. 1 May 2012. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2012/WD-css3-writing-modes-20120501/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
Other references[CSS3UI]
Tantek Çelik. CSS Basic User Interface Module Level 3 (CSS3 UI). 17 January 2012. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2012/WD-css3-ui-20120117/
[CSS3VAL]
Håkon Wium Lie; Tab Atkins; Elika J. Etemad. CSS Values and Units Module Level 3. 28 August 2012. W3C Candidate Recommendation. (Work in progress.) URL: http://www.w3.org/TR/2012/CR-css3-values-20120828/
[HTML40]
Ian Jacobs; David Raggett; Arnaud Le Hors. HTML 4.0 Specification. 24 April 1998. W3C Recommendation. URL: http://www.w3.org/TR/1998/REC-html40-19980424
Changes The following significant changes were made since the 12 June 2012 Last Call Working Draft :
All children of a flex container now become flex items (not just those that are not ‘inline
’).
Defined painting behavior of flex items .
Made ‘z-index
’ automatically apply to flex items.
Changed how absolutely-positioned flex container children are handled so that they don't impact layout.
Defined which properties apply to the table wrapper box vs. the table box of a table element.
Defined interaction of ‘order ’ and speech , ‘nav-index’ .
Corrected errors in the flex layout algorithm .
Defined baselines in flex layout .
Various clarifications to the flex containers and flex items chapters.
Clarified parsing of the ‘flex ’ shorthand and unitless zeroes.
Added or rewrote many examples to make them more realistic and more interesting.
A Disposition of Last Call Comments is available.
Property index
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
display
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
0
flex items
no
visual
flex-shrink
1
flex items
no
visual
flex
none | [ <'flex-grow'> <'flex-shrink'>?
<'flex-basis'> ]
see individual properties
flex items
see individual properties
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
min-width, min-height
order
0
flex items
no
visual
Index
align-content, 8.4.
align-items, 8.3.
align-self, 8.3.
align-self: auto, 8.3.
authoring tool, 11.2.
‘baseline ’,8.3.
‘center ’, 8.3. , 8.4. , 8.2.
collapsed, 4.4.
collapsed flex item, 4.4.
‘column ’,5.1.
‘column-reverse ’, 5.1.
cross axis, 2.
cross-axis baseline, 8.5.
cross dimension, 2.
cross-end, 2.
cross size, 2.
cross size property, 2.
cross-start, 2.
definite, 9.
definite size, 9.
flex, 7.1. , 3.
‘flex ’, 3.
flex base size, 9.2.
flex basis, 7.1.
flex-basis, 7.3.3.
flex-basis: auto, 7.3.3.
flex container, 3.
flex-direction, 5.1.
‘flex-end ’, 8.4. , 8.3. , 8.2.
flex-flow, 5.3.
flex formatting context, 3.
flex-grow, 7.3.1.
flex grow factor, 7.1.
flexible length, 7.1.
flexible length's, 7.1.
flex item, 4.
flex layout, 1.
flex-shrink, 7.3.2.
flex shrink factor, 7.1.
‘flex-start ’, 8.4. , 8.3. , 8.2.
flex-wrap, 5.2.
hypothetical cross size, 9.4.
hypothetical main size, 9.2.
indefinite, 9.
indefinite size, 9.
‘inline-flex ’, 3.
inline-flex, 3.
justify-content, 8.2.
main axis, 2.
main-axis baseline, 8.5.
main dimension, 2.
main-end, 2.
main size, 2.
main size property, 2.
main-start, 2.
min-width/height:auto, 4.5.
multi-line, 6.
‘none ’, 7.1.
‘nowrap ’,5.2.
order, 5.4.
participates in baseline alignment, 8.3.
renderer, 11.2.
‘row ’, 5.1.
‘row-reverse ’, 5.1.
scaled flex shrink factor, 9.7.
single-line, 6.
‘space-around ’, 8.4. , 8.2.
‘space-between ’, 8.4. , 8.2.
static position, 4.1.
‘stretch ’, 8.4. , 8.3.
strut size, 9.4.
style sheet
as conformance class, 11.2.
‘wrap ’, 5.2.
‘wrap-reverse ’, 5.2.