CSS Flexible Box Layout Module (original) (raw)

W3C

W3C Candidate Recommendation, 18 September 2012

This version:

http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/

Latest version:

http://www.w3.org/TR/css3-flexbox/

Editor's Draft:

http://dev.w3.org/csswg/css3-flexbox/

Previous version:

http://www.w3.org/TR/2012/WD-css3-flexbox-20120612/

Issues List:

Bugzilla Bugs for Flexbox

Discussion:

www-style@w3.org with subject line "[css3-flexbox] …message topic…"

Editors:

Tab Atkins Jr., Google Inc.

Elika J. Etemad, Mozilla

Alex Mogilevsky, Microsoft Corporation, alexmog@microsoft.com

Authors and former editors:

L. David Baron, Mozilla Corporation, dbaron@dbaron.org

Neil Deakin, Mozilla Corporation, enndeakin@gmail.com

Ian Hickson, formerly of Opera Software, ian@hixie.ch

David Hyatt, formerly of Netscape Corporation, hyatt@apple.com

Copyright © 2012 W3C® (MIT, ERCIM,Keio), All Rights Reserved. W3C liability,trademark and document use rules apply.


Abstract

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.

Status of this document

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/.

This document was produced by the CSS Working Group as a Candidate Recommendation.

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.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

The CR period will last at least until 20 March 2013. At the time of publication, no test suite and implementation report have yet been made. They will be made available from the CSS test suites page. See the section “CR exit criteria” for details.

See the section “Changes” for changes made to this specification since the last Working Draft.

The following features are at-risk:

Table of contents

1. Introduction

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.

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 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:

Computer Starter Kit

This is the best computer money can buy, if you don't have much money.

  • Computer
  • Monitor
  • Keyboard
  • Mouse
You get: a white computer with matching peripherals. BUY NOW

You get: a white computer with matching keyboard and monitor.

Computer Starter Kit

This is the best computer money can buy, if you don't have much money.

You get: beautiful ASCII art.

Printer

Only capable of printing ASCII art.

An example rendering of the code above.

1.2. Module interactions

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. It also defines a new initial value for ‘min-width’ and ‘min-height’. None of the properties defined in this module apply to the ‘::first-line’ or ‘::first-letter’ pseudo-elements.

1.3. Values

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 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.

2. Flex Layout Box Model and Terminology

An element with ‘display:flex’ or ‘display:inline-flex’ is a flex container. Children of a flex container are called flex items and are laid out using the flex layout model.

Unlike block and inline layout, whose layout calculations are biased to the block and inline flow directions, flex layout is biased to the flex flow directions. To make it easier to talk about flex layout, this section defines a set of flex flow–relative terms. The ‘flex-flow’ value determines how these terms map to physical directions (top/right/bottom/left), axes (vertical/horizontal), and sizes (width/height).

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

A flex item's width or height, whichever is in the main dimension, is the item's main size. The flex item's main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.

cross axis

cross dimension

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 width or height of a flex item, whichever is in the cross dimension, is the item's cross size. Thecross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.

3. Flex Containers: the ‘flex’ and ‘inline-flex’display’ values

Name: display
New value: flex | inline-flex

flex

This value causes an element to generate a block-level flex container box.

inline-flex

This value causes an element to generate a inline-level flex container box.

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:

If an element's specified ‘display’ is ‘inline-flex’ and the element is floated or absolutely positioned, the computed value of ‘display’ is ‘flex’. The table in CSS 2.1 Chapter 9.7 is thus amended to contain an additional row, with ‘inline-flex’ in the "Specified Value" column and ‘flex’ in the "Computed Value" column.

4. Flex Items

The contents of a flex container consists of zero or more flex items: each 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 is not rendered, as if it were ‘display:none’.

Authors reading this spec may want to skip past these box-generation details.

A flex item establishes a new formatting context for its contents. The type of this formatting context is determined by its ‘display’ value, as usual. The computed ‘display’ of a flex item is determined by applying the table in CSS 2.1 Chapter 9.7. However, flex items are flex-level boxes, not block-level boxes: they participate in their container's flex formatting context, not in a block formatting context.

The ‘display’ computation on flex items as defined here is expected to be superseded by a future specification that defines a new ‘display’ value specific to flex items.

Examples of flex items:

<!-- 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>

Some values of ‘display’ trigger the generation of anonymous boxes. For example, a misparented ‘table-cell’ child is fixed up by generating anonymous ‘table’ and ‘table-row’ elements around it. [CSS21] This fixup must occur_before_ a flex container's children are promoted to flex items. For example, given two contiguous child elements with ‘display:table-cell’, an anonymous table wrapper box around them becomes the flex item.

Future display types may generate anonymous containers (e.g. ruby) or otherwise mangle the box tree (e.g. run-ins). It is intended that flex item determination run after these operations.

On a flex item with ‘display: table’, the table wrapper box becomes the flex item, and the ‘order’ and ‘align-self’ properties apply to it. The contents of any caption boxes contribute to the calculation of the table wrapper box's min-content and max-content sizes. However, like ‘width’ and ‘height’, the ‘flex’ longhands apply to the table box as follows: the flex item's final size is calculated by performing layout as if the distance between the table wrapper box's edges and the table box's content edges were all part of the table box's border+padding area, and the table box were the flex item.

4.1. Absolutely-Positioned Flex Items

An absolutely-positioned flex item 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’, theflex item must be positioned so that itsmain-start or cross-start edge (whichever is in the horizontal axis) is aligned with the static position. If both ‘top’ and ‘bottom’ are ‘auto’, theflex item must be positioned so that itsmain-start or cross-start edge (whichever is in the vertical axis) is aligned with the static position.

In the main axis,

  1. If there is a subsequent in-flow flex item on the same flex line, the static position is the outermain-start edge of that flex item.
  2. Otherwise, if there is a preceding in-flow flex item on the same flex line, thestatic position is the outer main-end edge of that flex item.
  3. 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,

  1. 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.
  2. 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.

4.2. Flex Item Margins

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.

4.3. Flex Item Painting

Flex items paint exactly the same as block-level elements in the normal flow, except that ‘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.

4.4. Collapsed Items

Specifying ‘visibility:collapse’ on a flex item causes it to become a collapsed flex item, producing an effect similar to ‘visibility:collapse’ on a table-row or table-column: the collapsed element is removed from rendering entirely, but leaves behind a "strut" that keeps the flex line's cross-size stable. Thus, if a flex container has only one flex line, dynamically collapsing or uncollapsing items is guaranteed to have no effect on the flex container's cross size and won't cause the rest of the page's layout to "wobble". Flex line wrapping is re-done after collapsing, however, so the cross-size of a flex container with multiple lines might or might not change.

Though collapsed flex items aren't rendered, they do appear in the formatting structure. Therefore, unlike on ‘display:none’ items [CSS21], effects that depend on an element appearing in the formatting structure (like incrementing counters or running animations and transitions) still operate on collapsed items.

In the following example, a sidebar is sized to fit its content. ‘Visibility: collapse’ is used to dynamically hide parts of a navigation sidebar without affecting its width, even though the widest item (“Architecture”) is in a collapsed section.

Sample rendering for example code below

Interesting Stuff to Read

Interesting Stuff to Read