Copyright © 2014 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. CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, in speech, etc.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Publication as a Last Call Working Draft 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 (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 “css-flexbox” in the subject, preferably like this: “[css-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.
This specification is a Last Call Working Draft. All persons are encouraged to review this document and send comments to the www-style mailing list as described above. The deadline for comments is 22 April 2014.
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:
<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.
A flex container is the box generated by an element with a computed display of flex or inline-flex. In-flow 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 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).
Name: | display |
---|---|
New values: | 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:
If an element’s specified display is inline-flex, then its display property computes to flex in certain circumstances: the table in CSS 2.1 Section 9.7 is amended to contain an additional row, with inline-flex in the "Specified Value" column and flex in the "Computed Value" column.
Loosely speaking, the flex items of a flex container are the in-flow boxes generated from the contents of the element that generated the flex container.
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. However, an anonymous flex item that contains only white space (i.e. characters that can be affected by the white-space property) is not rendered, as if it were display:none.
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. However, flex items themselves are flex-level boxes, not block-level boxes: they participate in their container’s flex formatting context, not in a block formatting context.
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>
Authors reading this spec may want to skip past the following box-generation details.
If the specified display-outside of an in-flow child of an element that generates a flex container is inline-level, it computes to block-level. (This effectively converts any inline display values to their block equivalents.)
Note: Some values of display-outside trigger the creation of anonymous boxes around the original box. It’s the outermost box, the direct child of the flex container box, that becomes a flex item. For example, given two contiguous child elements with display:table-cell, an anonymous table wrapper box around them becomes the flex item.
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 of a flex container does not participate in flex layout beyond the reordering step.
Its static position is calculated by first doing full flex layout without the absolutely-positioned children, then positioning each absolutely-positioned child as if it were the sole flex item in the flex container, assuming both the child and the flex container were fixed size boxes of their used size.
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 inline blocks [CSS21], 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 flex item 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 a box 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.)
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 values: | auto |
New computed value: | the percentage as specified or the absolute length or a keyword |
New initial value: | auto |
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.)
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.
Name: | flex-direction |
---|---|
Value: | row | row-reverse | column | column-reverse |
Initial: | row |
Applies to: | flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
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.
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.
Name: | flex-wrap |
---|---|
Value: | nowrap | wrap | wrap-reverse |
Initial: | nowrap |
Applies to: | flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
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.
Name: | flex-flow |
---|---|
Value: | <flex-direction> || <flex-wrap> |
Initial: | see individual properties |
Applies to: | flex containers |
Inherited: | see individual properties |
Media: | visual |
Computed value: | see individual properties |
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; |
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 children of flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
Animatable: | yes |
The order property controls the order in which flex items appear within their flex container, by assigning them to ordinal groups. It takes a single "><integer> value, which specifies which ordinal group the flex item belongs to.
A flex container lays out its content in order-modified document order, 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 flex items were reordered in the source 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 boxes 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.)
Flex items in a flex container are laid out and aligned within flex lines, hypothetical containers used for grouping and alignment by the layout algorithm. A flex container can be either single-line or multi-line, depending on the flex-wrap property:
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.
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.
Name: | flex |
---|---|
Value: | none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ] |
Initial: | see individual properties |
Applies to: | flex items |
Inherited: | see individual properties |
Media: | visual |
Computed value: | 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 a box is a flex item, flex is consulted instead of the main size property to determine the main size of the box. If a box is not a flex item, flex has no effect.
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.
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.
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 0%.
If the specified flex-basis is auto, the used flex basis is the value of the flex item’s main size property. (This can itself be the keyword auto, which sizes the flex item based on its contents.)
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.
This section is informative.
The list below summarizes the effects of the most common flex values:
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See Implied Minimum Size of Flex Items.)
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.
Name: | flex-grow |
---|---|
Value: | "><number> |
Initial: | 0 |
Applies to: | flex items |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
Animatable: | yes, except between 0 and other values |
The flex-grow property sets the flex grow factor to the provided "><number>. Negative numbers are invalid.
Name: | flex-shrink |
---|---|
Value: | "><number> |
Initial: | 1 |
Applies to: | flex items |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
Animatable: | yes, except between 0 and other values |
The flex-shrink property sets the flex shrink factor to the provided "><number>. Negative numbers are invalid.
Name: | flex-basis |
---|---|
Value: | auto | <‘width’> |
Initial: | auto |
Applies to: | flex items |
Inherited: | no |
Media: | visual |
Computed value: | as specified, with lengths made absolute |
Percentages: | realtive to the flex container’s inner main size |
Animatable: | as width |
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 the same as a main size of auto. 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.
This 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:
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.
Name: | justify-content |
---|---|
Value: | flex-start | flex-end | center | space-between | space-around |
Initial: | flex-start |
Applies to: | flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
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.
An illustration of the five justify-content keywords and their effects on a flex container with three colored items.
Name: | align-items |
---|---|
Value: | flex-start | flex-end | center | baseline | stretch |
Initial: | stretch |
Applies to: | flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
Name: | align-self |
---|---|
Value: | auto | flex-start | flex-end | center | baseline | stretch |
Initial: | auto |
Applies to: | flex items |
Inherited: | no |
Media: | visual |
Computed value: | auto computes to parent’s align-items value; otherwise as specified |
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:
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.
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-height/min-width/max-height/max-width.
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.
Name: | align-content |
---|---|
Value: | flex-start | flex-end | center | space-between | space-around | stretch |
Initial: | stretch |
Applies to: | multi-line flex containers |
Inherited: | no |
Media: | visual |
Computed value: | specified value |
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:
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:
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.
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. An indefinite size is one that is not definite.
As a special case for handling stretched flex items, if a single-line flex container has a definite cross size, the outer cross size of any flex items with align-self: stretch is the flex container’s inner cross size (clamped to the flex item’s min and max cross size) and is considered definite.
The following sections define the algorithm for laying out a flex container and its contents.
For example, the available space to a flex item in a floated auto-sized flex container is:
The hypothetical main size is the item’s flex base size clamped according to its min and max main size properties.
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.
If the flex container has only one flex 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:
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.
If the flex item has align-self: stretch, redo layout for its contents, treating this used size as its definite cross size so that percentage-sized children can be resolved.
Note that this step does not affect the main size of the flex item, even if it has an intrinsic aspect ratio.
To resolve the flexible lengths of the items within a flex line:
Otherwise, if the free space is negative, then first sum the flex shrink factors of all the flex items on the line. If this number is greater than 1, set it to 1. Let this result be the scaled flex factor sum. For each flex item, multiply its flex shrink factor by its used based size. Then, renormalize each flex shrink factor so that their sum is the scaled flex factor sum. Then, multiple the flex shrink factor by the free space, and let the result be the originally desired free space.
Otherwise, if the free space is negative, and the sum of the desired free spaces of all the non-frozen flex items on the line is less than the free space, normalize all the desired free spaces so that they sum exactly to the free space while maintaining their magnitudes relative to each other.
Note: This may result in a negative main size temporarily.
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-size contributions in the main axis. The min-content main size of a single-line flex container is the sum of the flex container’s items' min-size contributions in the main axis; 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-size contribution of a flex item is its outer hypothetical main size when sized under a min-content/max-size 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 the contents of 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:
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.
Any flex items that fit entirely into previous fragments still take up space in the main axis in later fragments.
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.
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, Peter Moulder, 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:
- 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 ([CSS3-SIZING]) is sufficiently mature.
On a flex item whose overflow is not visible, this keyword specifies as the minimum size the smaller of:
- the min-content size, or
- the computed width/height, if that value is definite.
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.
As a special case for handling stretched flex items, if a single-line flex container has a definite cross size, the outer cross size of any flex items with align-self: stretch is the flex container’s inner cross size (clamped to the flex item’s min and max cross size) and is considered definite.
If the flex item has align-self: stretch, redo layout for its contents, treating this used size as its definite cross size so that percentage-sized children can be resolved.
Note that this step does not affect the main size of the flex item, even if it has an intrinsic aspect ratio.
If the flex item has ...
- an intrinsic aspect ratio,
- a flex basis of auto, and
- a definite cross size
then the flex base size is calculated from its inner cross size and the flex item’s intrinsic aspect ratio.
If a cross size is needed to determine the main size (e.g. when the flex item’s main size is in its block axis) and the flex item’s cross size is auto and not definite, in this calculation use fit-content as the flex item’s cross size.
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’.
The max-content main size of a flex container is the sum of the flex container’s items' max-size contributions in the main axis. The min-content main size of a single-line flex container is the sum of the flex container’s items' min-size contributions in the main axis; 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-size contribution of a flex item is its outer hypothetical main size when sized under a min-content/max-size constraint (respectively).
See [CSS3-SIZING] for a definition of the terms in this section.
If the flex container has only one flex 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.
The used cross-size of the flex line is the
largerlargest of the numbers found in the previous two steps and zero.
Flex items paint exactly the same as
block-level elements in the normal flowinline blocks [CSS21].
When omitted from the flex shorthand, its specified value is 0%
the length zero.
- flex: <positive-number>
- Equivalent to flex: <positive-number> 1
0px0%.
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
undefinedthe same as a main size of auto.
An absolutely-positioned child 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 flex item 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 flex item 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,
- If there is a subsequent in-flow flex item on the same flex line, the static position is the outer main-start edge of that flex item.
- Otherwise, if there is a preceding in-flow flex item on the same flex line, the static position is the outer main-end edge of that flex item.
- Otherwise, the static position is determined by the value of justify-content on the flex container as if the static position were represented by a zero-sized flex item.
In the cross axis,
- If there is a preceding in-flow flex item, the static position is the cross-start edge of the flex line that item is in.
- Otherwise, the static position is the cross-start edge of the first flex line.
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.
Its static position is calculated by first doing full flex layout without the absolutely-positioned children, then positioning each absolutely-positioned child as if it were the sole flex item in the flex container, assuming both the child and the flex container were fixed size boxes of their used size.
For example, by default, the static position of an absolutely positioned child aligns it to the main-start/cross-start corner, corresponding to the default values of justify-content and align-content on the flex container. Setting justify-content:center on the flex container, however, would center it in the main axis.
The following significant clarifications were also made:
Name: order Applies to: flex items and absolutely-positioned children of flex containers
Re-order the flex items and absolutely positioned flex container children according to their order.
float and clear have no effect on a flex item, and do not take it out-of-flow. However, the float property can still affect box generation by influencing the display property’s computed value.
However, an anonymous flex item that contains only white space (i.e. characters that can be affected by the white-space property) is not rendered, as if it were display:none.
If the specified display-outside of an in-flow child of an element that generates a flex container is inline-level, it computes to block-level. (This effectively converts any inline display values to their block equivalents.)
- stretch
If the cross size property of the flex item
iscomputes to auto, its used value is …
Determine the used cross size of each flex item. If a flex item has align-self: stretch, its computed cross size property is auto, and …
Determine the main size of the flex container using the rules of the formatting context in which it participatesits main size property.
Otherwise, starting from the first uncollected item, collect consecutive items one by one until the first time that the next collected item would not fit into the flex container’s inner main size, or until a forced break is encountered. If the very first uncollected item wouldn’t fit, collect just it into the line
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.
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 collectthemzero-sized flex items onto the end of the previous line even if the last non-zero item exactly "filled up" the line.
- If the cross size property is a definite size, use that, clamped by the min and max cross size properties of the flex container.
- Otherwise, use the sum of the flex lines' cross sizes, clamped by the min and max cross size properties of the flex container.
A Disposition of Candidate Recommendation Comments is available.
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 this specification is defined for three conformance classes:
A style sheet is conformant to this specification 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 this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification 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 this specification 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 implementors 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.
Name | Value | Initial | Applies to | Inh. | %ages | Media | Animatable | Canonical order | Computed value |
---|---|---|---|---|---|---|---|---|---|
flex-direction | row | row-reverse | column | column-reverse | row | flex containers | no | visual | specified value | |||
flex-wrap | nowrap | wrap | wrap-reverse | nowrap | flex containers | no | visual | specified value | |||
flex-flow | <flex-direction> || <flex-wrap> | see individual properties | flex containers | see individual properties | visual | see individual properties | |||
order | <integer> | 0 | flex items and absolutely-positioned children of flex containers | no | visual | yes | specified value | ||
flex | none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ] | see individual properties | flex items | see individual properties | visual | per grammar | see individual properties | ||
flex-grow | <number> | 0 | flex items | no | visual | yes, except between 0 and other values | specified value | ||
flex-shrink | <number> | 1 | flex items | no | visual | yes, except between 0 and other values | specified value | ||
flex-basis | auto | <‘width’> | auto | flex items | no | realtive to the flex container’s inner main size | visual | as width | as specified, with lengths made absolute | |
justify-content | flex-start | flex-end | center | space-between | space-around | flex-start | flex containers | no | visual | specified value | |||
align-items | flex-start | flex-end | center | baseline | stretch | stretch | flex containers | no | visual | specified value | |||
align-self | auto | flex-start | flex-end | center | baseline | stretch | auto | flex items | no | visual | auto computes to parent’s align-items value; otherwise as specified | |||
align-content | flex-start | flex-end | center | space-between | space-around | stretch | stretch | multi-line flex containers | no | visual | specified value |