Flexbox Level 1 defined a new layout mode: flex layout.
Flex layout is a powerful, flexible layout mode
for laying out a flex container’s children (flex items)
across one or several lines,
either horizontally or vertically,
and aligning or stretching the items within their line in various ways
that are generally useful for application or whole-page layouts.
This level extends the flex layout model in a number of ways:
flex-wrap: balance allows for flex items to be balanced across lines,
so each line is as similar in length as possible,
avoiding "jagged" lines, particularly on the last line.
1.1.
Overview
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 web apps and complex web pages often need.
The contents of a flex container:
can be laid out in any flow direction
(leftwards, rightwards, downwards, or even upwards!)
can have their display order reversed or
'order|rearranged' at the style layer
(i.e., visual order can be independent of source and speech order)
can be laid out linearly along a single (main) axis or
wrapped into multiple lines along a secondary (cross) axis
if multi-line, can be packed tightly onto each line
(similar to standard text line-breaking)
or balanced across the lines
(similar to text-wrap:pretty)
Here’s an example of a catalog where each item has a title, a 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 are aligned at the bottom, regardless of the length of the item’s description.
Flex layout makes many aspects of this design easy:
The catalog uses flex layout to lay out rows of items horizontally,
and to ensure that items within a row are all equal-height.
Each entry is then itself a column flex container,
laying out its contents vertically.
Within each entry, the source document content is ordered logically
with the title first, followed by the description and the photo.
This provides a sensible ordering for speech rendering and in non-CSS browsers.
For a more compelling visual presentation, however,
order is used to pull the image up from later in the content to the top,
and align-self is used to center it horizontally.
An auto margin above the purchase button
forces it to the bottom within each entry box,
regardless of the height of that item’s description.
<sectionid="deals"><sectionclass="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><imgsrc="images/computer.jpg"alt="You get: a white computer with matching peripherals."><button>BUY NOW</button></section><sectionclass="sale-item">
…
</section>
…
</section>
Computer Starter Kit
This is the best computer money can buy,
if you don’t have much money.
Computer
Monitor
Keyboard
Mouse
Printer
Only capable of printing
ASCII art.
Paper and ink not included.
An example rendering of the code above.
1.2.
Module interactions
This module extends the definition of the display property [CSS2],
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.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the CSS-wide keywords as their property value.
For readability they have not been repeated explicitly.
2.
Flex Layout Box Model and Terminology
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 and the writing mode
determine how these terms map
to physical directions (top/right/bottom/left),
axes (vertical/horizontal), and sizes (width/height).
An illustration of the various directions and sizing terms as applied to a row flex container.
main axis
main dimension
The main axis of a flex container is the primary axis along which flex items are laid out.
It extends in the main dimension.
main-start
main-end
The flex items are placed within the container
starting on the main-start side
and going toward the main-end side.
main size
main size property
The main size of a flex container or flex item
refers to its width or height,
whichever is in the main dimension.
Its main size property
is either its width or height property,
whichever is in the main dimension.
Likewise, its min and
max main size properties
are its min-width/max-width or min-height/max-height properties,
whichever are in the main dimension,
and determine its min/max main size.
The axis perpendicular to the main axis is called the cross axis.
It extends in the cross dimension.
cross-start
cross-end
Flex lines are filled with items and placed into the container
starting on the cross-start side of the flex container
and going toward the cross-end side.
cross size
cross size property
The cross size of a flex container or flex item
refers to its width or height,
whichever is in the cross dimension.
Its cross size property
is either its width or height property,
whichever is in the cross dimension.
Likewise, its min and
max cross size properties
are its min-width/max-width or min-height/max-height properties,
whichever are in the cross dimension,
and determine its min/max cross size.
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.
For example, 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. [CSS2]
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.
<divstyle="display:flex"><!-- flex item: block child --><divid="item1">block</div><!-- flex item: floated element; floating is ignored --><divid="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 --><qstyle="display: block"id=not-an-item>item 4</q>
item 4
</span></div>
Flex items determined from above code block
Note that the inter-element white space disappears:
it does not become its own flex item,
even though the inter-element text does get wrapped in an anonymous flex item.
Note also that the anonymous item’s box is unstyleable,
since there is no element to assign style rules to.
Its contents will however inherit styles (such as font settings) from the flex container.
A flex itemestablishes an independent formatting context for its contents.
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.
Note: Some values of display normally trigger the creation of anonymous boxes around the original box.
If such a box is a flex item,
it is blockified first,
and so anonymous box creation will not happen.
For example, two contiguous flex items with display: table-cell
will become two separate display: blockflex items,
instead of being wrapped into a single anonymous table.
In the case of flex items with display: table,
the table wrapper box becomes the flex item,
so the align-self property applies 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.
As it is out-of-flow,
an absolutely-positioned child of a flex container does not participate in flex layout.
The cross-axis edges of the static-position rectangle
of an absolutely-positioned child of a flex container
are the content edges of the flex container.
The main-axis edges of the static-position rectangle
are where the margin edges of the child would be positioned
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 this purpose,
the child’s auto margins are treated as zero.)
The effect of this is that if you set, for example,
align-self: center; on an absolutely-positioned child of a flex container,
auto offsets on the child will center it in the flex container’scross axis.
Percentage margins and paddings on flex items,
like those on block boxes,
are resolved against the inline size of their containing block,
e.g. left/right/top/bottom percentages
all resolve against their containing block’s width
in horizontal writing modes.
Auto margins expand to absorb extra space in the corresponding dimension.
They can be used for alignment,
or to push adjacent flex items apart.
See Aligning with auto margins.
Flex items paint exactly the same as inline blocks [CSS2],
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
(behaving exactly as if position were relative).
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
may change the flex container’s main size, but
is guaranteed to have no effect on its 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 [CSS2],
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.
Sample live rendering for example code below
Hover over the menu to the left:
each section expands to show its sub-items.
In order to keep the sidebar width (and this main area width) stable,
visibility: collapse is used instead of display: none.
This results in a sidebar that is always wide enough for the word “Architecture”,
even though it is not always visible.
@media(min-width: 60em){/* two column layout only when enough room (relative to default text size) */
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 targeted */
nav > ul > li:not(:target):not(:hover) > ul {visibility: collapse;}
To compute the size of the strut, flex layout is first performed with all items uncollapsed,
and then re-run with each collapsed flex 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: 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.
Automatic Minimum Size of Flex Items
Note: The auto keyword,
representing an automatic minimum size,
is the new initial value of the min-width and min-height properties.
The keyword was previously defined in this specification,
but is now defined in the CSS Sizing module.
For the purpose of calculating an intrinsic size of the box
(e.g. the box’s min-content size),
a content-based minimum size causes the box’s size in that axis to become indefinite
(even if e.g. its width property specifies a definite size).
Note this means that percentages calculated against this size
will behave as auto.
For any purpose other than calculating intrinsic sizes,
a content-based minimum size
(unlike an explicit min-content/etc minimum size)
does not force the box’s size to become indefinite.
However, if a percentage resolved against the box’s size before this minimum was applied,
it must be re-resolved against the new size after it is applied.
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.
Note: 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 CSS Display 3 § 3.1 Reordering and Accessibility
and the Flex Layout Overview for examples
that use this dichotomy to improve accessibility.
Authors must not use order or the *-reverse values of flex-flow/flex-direction
as a substitute for correct source ordering,
as that can ruin the accessibility of the document.
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 in which flex items are laid out.
Note: 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.
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.
The flex container is multi-line,
but the lines are stacked "in reverse" (see below).
balance
The flex container is multi-line,
and attempts to balance the lengths of the flex lines
to be as similar as possible.
balance can be combined with wrap or wrap-reverse
to dictate which direction the flex lines are stacked in.
If neither are specified,
it behaves as if wrap was specified.
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 wrapping. (Items will either shrink to fit or overflow.) */
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; writing-mode: horizontal-tb;
flex-flow: row wrap; writing-mode: vertical-rl;
5.4.
Reordering and Accessibility: the order property
Flex items are, by default, displayed and laid out
in the same order as they appear in the source document,
which represents their logical ordering.
This same order is used in rendering to non-visual media
(such as speech),
in the default traversal order of sequential navigation modes
(such as cycling through links,
see e.g. tabindex[HTML]),
and when content is represented in non-CSS UAs.
Note: Since visual perception is two-dimensional and non-linear,
the desired box order is not always the same logical order
used by non-visual media and non-CSS UAs.
Authors must use order only for visual, not logical, reordering of content.
Style sheets that use order to perform logical reordering are non-conforming.
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 {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.)
6.
Flex Lines
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:
A single-line flex container
(i.e. one with flex-wrap: nowrap)
lays out all of its children in a single line,
even if that would cause its contents to overflow.
A multi-line flex container
(i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse)
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.
Additionally, a multi-line flexbox can be
a balanced flex container,
meaning it carefully chooses its linebreaks
to make the line lengths as similar as possible.
(Otherwise, it simply fills the first line, then the second, etc.)
This example shows four buttons that do not fit side-by-side horizontally,
and therefore will wrap into multiple lines.
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.
An example rendering of the multi-line flex container.
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.
In a multi-lineflex container (even one with only a single line),
the cross size of each line
is the minimum size necessary to contain the flex items on the line
(after alignment due to align-self),
and the lines are aligned within the flex container with the align-content property.
In a single-lineflex container,
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 receive 20px of extra width,
each ending up 100px wide.
The remaining item is on a line of its own
and will stretch to the entire width of the line, i.e. 300px.
A rendering of the same as above,
but with the items all given flex: auto.
The above examples show three items fitting on a single line,
leaving a single item on the second line.
flex-wrap: balance will instead put two items on the first line,
then two on the second line:
The previous example’s four items,
but now balanced across the two lines
with flex-wrap: balance.
This can have more dramatic effects when flexing items to fill the line,
as the items are more likely to flex similar amounts,
rather than the final line’s items flexing a lot more:
By default, a balance flexbox
will create as many lines as a normal multi-line flexbox,
then rebalance how the flex items are assigned across that many lines.
In some situations,
an author might want to ensure there are always a certain number of lines,
or might be using a flexbox in a way where there is no limit to the line length
(the standard for a column flexbox, with unlimited available height)
and so the "default" line number calculation is useless.
The flex-line-count property specifies a minimum flex line count
that the flex container should create
to balance the items across.
The minimum flex line count is clamped from above
by the number of flex items in the flex container;
it will only create as many lines as there are flex items.
(That is, if you specify flex-line-count: 3
but only have two flex items,
the minimum flex line count is 2, instead.)
Note: There is no maximum flex line count;
the flex container will always contain enough lines
to hold all of its flex items,
which might be more than what flex-line-count specifies.
Unused lines (ones with no flex items assigned to them)
are discarded and do not affect layout.
This only affects non-balance flexboxes.
A balance flexbox will always assign at least one flex item to each line,
and if it has less items than flex-line-count,
that’s handled specially, above.
In addition to setting a minimum number of lines that are used by balance,
flex-line-count changes the available space in the cross axis for flex items:
subtracting the size of N-1 gaps from the normal available space,
then dividing the leftover by N,
where N is the flex-line-count value.
This uses the actual flex-line-count value,
not the minimum flex line count
or the actual number of generated lines
(which can be higher or lower than what is specified).
Percentages continue to resolve as normal,
unaffected by this available space adjustment.
(To have a flex item fill the cross-axisavailable space,
use height: stretch,
rather than height: 100%.)
The defining aspect of flex layout is the ability to make the flex items “flex”,
altering their width/height to fill the available space in the main dimension.
This is done with the flex property.
A flex container distributes free space to its items (proportional to their flex grow factor) to fill the container,
or shrinks them (proportional to their flex shrink factor) to prevent overflow.
The flex property specifies the components of a flexible size:
the flex factors
(grow and shrink)
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.
Note: The initial values of the flex longhands are equivalent to
flex: 0 1 auto.
This differs from their defaults when omitted in the flex shorthand
(effectively 1 1 0px)
so that the flex shorthand can better accommodate
the most common cases.
This <number [0,∞]> component sets flex-growlonghand
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.
Tests
You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.