- From: Tab Atkins Jr.. via cvs-syncmail <cvsmail@w3.org>
- Date: Wed, 24 Aug 2011 23:09:50 +0000
- To: public-css-commits@w3.org
Update of /sources/public/csswg/css3-flexbox In directory hutz:/tmp/cvs-serv27778 Modified Files: Overview.html Overview.src.html Log Message: Finished rewrite of the Flexibility chapter Index: Overview.html =================================================================== RCS file: /sources/public/csswg/css3-flexbox/Overview.html,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- Overview.html 23 Aug 2011 17:46:39 -0000 1.41 +++ Overview.html 24 Aug 2011 23:09:48 -0000 1.42 @@ -16,12 +16,12 @@ <h1 id=head-box-flexible>CSS Flexible Box Layout Module</h1> - <h2 class="no-num no-toc" id=w3c-working>Editor's Draft, 23 August 2011</h2> + <h2 class="no-num no-toc" id=w3c-working>Editor's Draft, 24 August 2011</h2> <dl> <dt>This version: - <dd><!-- <a href="http://www.w3.org/TR/2011/WD-css3-flexbox-20110823/">http://www.w3.org/TR/2011/WD-css3-flexbox-20110823/</a></dd> --> + <dd><!-- <a href="http://www.w3.org/TR/2011/WD-css3-flexbox-20110824/">http://www.w3.org/TR/2011/WD-css3-flexbox-20110824/</a></dd> --> <a href="http://dev.w3.org/csswg/css3-flexbox/">http://dev.w3.org/csswg/css3-flexbox/</a> @@ -155,14 +155,11 @@ <li><a href="#flexibility"><span class=secno>4. </span> Flexibility</a> <ul class=toc> - <li><a href="#resolving-flexible-lengths"><span class=secno>4.1. </span> - Resolving Flexible Lengths</a> - - <li><a href="#flex-function"><span class=secno>4.2. </span> The + <li><a href="#flex-function"><span class=secno>4.1. </span> The ‘<code class=css>flex()</code>’ function</a> - <li><a href="#flexible-margins"><span class=secno>4.3. </span> Flexible - margins and paddings</a> + <li><a href="#resolving-flexible-lengths"><span class=secno>4.2. </span> + Resolving Flexible Lengths</a> </ul> <li><a href="#flex-pack"><span class=secno>5. </span> The ‘<code @@ -385,7 +382,32 @@ ‘<code class=css>inline-flexbox</code>’ value makes the flexbox act like an inline-block in other layout modes. - <p>A flexbox establishes a new block formatting context for its content. + <p>Setting ‘<code class=css>display:flexbox</code>’ on an + element forces it to use a new layout algorithm, and so some properties + that were designed with the assumption of block layout don't make sense in + a flexbox context. In particular: + + <ul> + <li>all of the ‘<code class=css>column-*</code>’ properties in + the Multicol module compute to their initial values on a flexbox + (‘<code class=property>break-before</code>’, ‘<code + class=property>break-inside</code>’, and ‘<code + class=property>break-after</code>’ are still valid on a flexbox). + + <li>‘<code class=property>float</code>’ and ‘<code + class=property>clear</code>’ compute to their initial values on a + flexbox item + + <li>‘<code class=property>vertical-align</code>’ has no effect + on a flexbox item + </ul> + + <p>A flexbox item creates a new flexbox formatting context for its + contents. This is similar to a block formatting context: floats must not + intrude into the flexbox, and the flexbox's margins do not collapse with + any other margin. Additionally, all of the <a + href="#flexbox-item"><i>flexbox items</i></a> establish new block + formatting contexts for their contents. <p class=issue>Figure out the right terms to use here. @@ -412,6 +434,9 @@ <!-- flexbox item: block-level child --> <div id="item1">block</div> + + <!-- not a flexbox item, because it's out-of-flow --> + <div id="not-an-item1.5" style="position: absolute;">block</div> <!-- flexbox item: block-level child --> <div id="item2" style="display:table">table</div> @@ -420,10 +445,10 @@ <div id="item3" style="display:table-cell">table-cell</div> <!-- flexbox item: anonymous block around inline content --> - anonymous item 4 + anonymous item 4 <!-- flexbox item: block-level child --> - <div id="item5">block</div> + <div id="item5">block</div> <!-- flexbox item: anonymous block around inline content --> anonymous item 6.1 @@ -443,51 +468,65 @@ <button id="item8">button</button> <!-- flexbox item: inline-table --> - <div id="item9" style="display:inline-table">table</div> + <div id="item9" style="display:inline-table">table</div> </div></pre> <p>Notice that block element "not-an-item6.3" is not a separate flexbox item, because it is contained inside an inline element which is being - wrapped into an anonymous flex item.</p> + wrapped into an anonymous flex item. Similarly, the block element + "not-an-item1.5" is not a flexbox item, because it's absolutely + positioned and thus out of flow.</p> </div> - <p>Out-of-flow elements like absolutely positioned elements leave behind a - ‘<code class=property>placeholder</code>’ inline element in - their original position in the document - - <p class=issue>This needs to change. Placeholder is not fully hypothetical - in this case, that element or line is detectable in "flex-pack:justify". - TODO: define the "auto" position without a placeholder. - - <p>Setting ‘<code class=css>display:flexbox</code>’ on an - element forces it to use a new layout algorithm, and so some properties - that were designed with the assumption of block layout don't make sense in - a flexbox context. In particular: - - <ul> - <li>all of the ‘<code class=css>column-*</code>’ properties in - the Multicol module compute to their initial values on a flexbox - (‘<code class=property>break-before</code>’, ‘<code - class=property>break-inside</code>’, and ‘<code - class=property>break-after</code>’ are still valid on a flexbox). - - <li>‘<code class=property>float</code>’ and ‘<code - class=property>clear</code>’ compute to their initial values on a - flexbox item - - <li>‘<code class=property>vertical-align</code>’ has no effect - on a flexbox item - </ul> + <p>Absolutely positioned children of a flexbox are not <a + href="#flexbox-item"><i>flexbox items</i></a>, but their "static position" + (their position when the ‘<code + class=property>top</code>’/‘<code + class=property>right</code>’/‘<code + class=property>bottom</code>’/‘<code + class=property>left</code>’ properties are ‘<code + class=css>auto</code>’) responds somewhat to the flexbox's various + properties. The element's static position in the flexbox's <a + href="#cross-axis"><i>cross axis</i></a> is on the <a + href="#cross-start"><i>cross-start</i></a> edge of the flexbox's content + box. The static position in the flexbox's <a href="#main-axis"><i>main + axis</i></a> is slightly more complex to compute: - <p class=issue>It has been proposed that vertical-align property applies to - flex items (simliar to table cells). Decide if it makes sense, or if it - should instead apply broader (to any blocks). + <p>First, find the element's <dfn id=hypothetical-neighbors>hypothetical + neighbors</dfn> by assuming that the element is a normal <a + href="#flexbox-item"><i>flexbox item</i></a> with ‘<code + class=css>flex-order:1</code>’, and reorder the flexbox's contents + as mandated by ‘<a href="#flex-order0"><code + class=property>flex-order</code></a>’. The <a + href="#flexbox-item"><i>flexbox items</i></a> immediately preceding and + following (in the flexbox's direction) the element (if any) are the + element's <a href="#hypothetical-neighbors"><i>hypothetical + neighbors</i></a>. - <p>A flexbox item creates a new BFC. The margins of a flexbox item do not - collapse with any other margin. Flexboxes "shrinkwrap" their contents by - default (when their ‘<code class=property>width</code>’ or - ‘<code class=property>height</code>’ properties are - ‘<code class=css>auto</code>’), similar to tables or floats. + <p>If the element has two neighbors, its static position in the <a + href="#main-axis"><i>main axis</i></a> is exactly in the center of the + packing space between them when the flexbox is actually laid out. If the + element has only a preceding neighbor, its static position in the <a + href="#main-axis"><i>main axis</i></a> is flush with the <a + href="#main-end"><i>main-end</i></a> edge of the margin box of the + neighbor. If the element has only a following neighbor, its static + position in the <a href="#main-axis"><i>main axis</i></a> is flush with + the <a href="#main-start"><i>main-start</i></a> edge of the margin box of + the neighbor. Finally, if the element has no neighbors (the flexbox has no + in-flow children at all), the static position in the <a + href="#main-axis"><i>main axis</i></a> is based on the value of ‘<a + href="#flex-pack0"><code class=property>flex-pack</code></a>’: if + the value is ‘<a href="#flex-pack-start"><code + class=css>start</code></a>’ or ‘<a + href="#flex-line-pack-distribute"><code + class=css>distribute</code></a>’, it's flush with the <a + href="#main-start"><i>main-start</i></a> edge of the flexbox's content + box; if the value is ‘<a href="#flex-pack-end"><code + class=css>end</code></a>’, it's flush with the <a + href="#main-end"><i>main-end</i></a> edge of the flexbox's content box; if + the value is ‘<a href="#flex-pack-center"><code + class=css>center</code></a>’, it's centered within the flexbox's + content box. <h2 id=ordering-orientation><span class=secno>3. </span> Ordering and Orientation</h2> @@ -849,205 +888,200 @@ <h2 id=flexibility><span class=secno>4. </span> Flexibility</h2> - <p>The defining aspect of flexbox layout is the ability to make various - lengths of the <a href="#flexbox-item"><i>flexbox items</i></a> flexible. - The ‘<code class=property>width</code>’, ‘<code - class=property>height</code>’, ‘<code - class=property>padding</code>’, and ‘<code - class=property>margin</code>’ properties of a <a - href="#flexbox-item"><i>flexbox item</i></a> can all be made flexible. - Paddings and margins are made flexible by setting their value to - ‘<code class=css>auto</code>’, while the width and height of a - box can be controlled more precisely with the ‘<code + <p>The defining aspect of flexbox layout is the ability to make the <a + href="#flexbox-item"><i>flexbox items</i></a> "flex", altering their width + or height to fill the available space. This is done by declaring a <dfn + id=flexible-length>flexible length</dfn> with the ‘<code class=css>flex()</code>’ function, defined below. + <p>Flexible lengths are composed of a (non-flexible) preferred size and a + positive and negative flexibility. If there's free space left over in the + flexbox after subtracting the preferred sizes of all the <a + href="#flexbox-item"><i>flexbox items</i></a>, it is divided up among the + <a href="#flexbox-item"><i>flexbox items</i></a> proportionally to their + positive flexibility, making their width larger so they fill the space. + Conversely, if the flexbox's size is <em>less</em> than the sum of the + preferred sizes, so that the items would overflow normally, the <a + href="#flexbox-item"><i>flexbox items</i></a> are shrunk proportionally to + their negative flexibility, again so they exactly fit in the space. + <div class=example> <p class=issue>TODO: Examples!</p> </div> - <h3 id=resolving-flexible-lengths><span class=secno>4.1. </span> Resolving - Flexible Lengths</h3> - - <p>Flexbox layout resolves a <i>flexible length</i> into a definite length - by first collecting all the lengths, flexible or inflexible, that will - share some space. For example, for a horizontal flexbox, the lengths of - the left and right margins, left and right borders, left and right - paddings, and widths of all <a href="#flexbox-item"><i>flexbox - items</i></a> share the width of the flexbox itself. Conversely, each <a - href="#flexbox-item"><i title="flexbox item">flexbox item's</i></a> - vertical margins, borders, padding, and height individually share the - height of the flexbox. - - <div class=figure> - <p class="caption issue">TODO: Diagram showing the relevant lengths in - each axis.</p> - </div> - - <p>Flexbox layout then sums the <dfn id=pre-flex-size>pre-flex size</dfn> - of the lengths in each set. The <a href="#pre-flex-size"><i>pre-flex - size</i></a> of an inflexible length is just the length itself. The <a - href="#pre-flex-size"><i>pre-flex size</i></a> of a flexible length is its - <i>preferred size</i>. If the sum of all the <a href="#pre-flex-size"><i - title="pre-flex size">pre-flex sizes</i></a> is less than the available - width/height of the flexbox, then the difference is split up among all the - <i title="flexible length">flexible lengths</i> with <dfn - id=positive-flexibility>positive flexibility</dfn>, with the space divvied - up proportionally to the flexibility of each length. If the sum is greater - than the available width/height, then all the <i title="flexible - length">flexible lengths</i> with <dfn id=negative-flexibility>negative - flexibility</dfn> shrink in proportion to their flexibility to try and - make the sum equal the available width/height. - - <p>The ‘<a href="#flex-pack0"><code - class=property>flex-pack</code></a>’ and ‘<a - href="#flex-align0"><code class=property>flex-align</code></a>’ - properties offer additional options for free-space distribution. The - precise details of how free space is determined and assigned to flexible - lengths is detailed in a later chapter. - - <h3 id=flex-function><span class=secno>4.2. </span> The ‘<code + <h3 id=flex-function><span class=secno>4.1. </span> The ‘<code class=css>flex()</code>’ function</h3> <p>The ‘<code class=css>flex()</code>’ function is used to - specify the parameters of a <i>flexible length</i>: the <a - href="#positive-flexibility"><i title="positive - flexibility">positive</i></a> and <a - href="#negative-flexibility"><i>negative flexibility</i></a>, and the - <i>preferred size</i>. The syntax of the ‘<code - class=css>flex()</code>’ function is roughly (see following prose - for a precise description): + specify the parameters of a <dfn id=flexible-length0 title="flexible + length|flexible lengths|flexible length's">flexible length</dfn>: the <dfn + id=positive-flexibility title="positive flexibility">positive</dfn> and + <dfn id=negative-flexibility>negative flexibility</dfn>, and the <dfn + id=preferred-size>preferred size</dfn>. The syntax of the ‘<code + class=css>flex()</code>’ function is: <pre - class=prod>flex( [ <a href="#positive-flexibility"><i title="positive flexibility"><pos-flex></i></a> || <!-- - --><a href="#negative-flexibility"><i title="negative flexibility"><neg-flex></i></a> || <!-- - --><i title="preferred size"><preferred-size></i> ] )</pre> + class=prod>flex( [ <pos-flex> <neg-flex>? ]? || <preferred-size>? )</pre> - <p>Applicable to ‘<code class=property>width</code>’ and - ‘<code class=property>height</code>’ + <p><code><pos-flex></code> and <code><neg-flex></code> are + <code><integer>s</code>, while <code><preferred-size></code> is any + value (other than another ‘<code class=css>flex()</code>’ + function) that would be valid in the ‘<code + class=property>width</code>’ or ‘<code + class=property>height</code>’ property in which the function is + used, except that zero lengths must not omit their unit. - <p class=note>In the future this may be applicable to margin and padding + <p>The <code><pos-flex></code> component sets the length's <a + href="#positive-flexibility"><i>positive flexibility</i></a>; if omitted, + the <a href="#positive-flexibility"><i>positive flexibility</i></a> + defaults to ‘<code class=css>1</code>’. The + <code><neg-flex></code> component sets the length's <a + href="#negative-flexibility"><i>negative flexibility</i></a>; if omitted, + it defaults to ‘<code class=css>0</code>’. The + <code><preferred-size></code> component sets the length's <a + href="#preferred-size"><i>preferred size</i></a>; if omitted, it defaults + to ‘<code class=css>0px</code>’. - <dl> - <dt>If the ‘<code class=css>flex()</code>’ function contains a - single value: + <p class=issue>Examples! - <dd> - <ul> - <li>If the value is a non-negative number, the <a - href="#positive-flexibility"><i>positive flexibility</i></a> is set to - that value, the <a href="#negative-flexibility"><i>negative - flexibility</i></a> is set to ‘<code class=css>0</code>’, - and the <i>preferred size</i> is set to the initial value of the - property (‘<code class=property>auto</code>’ for width and - height). + <h3 id=resolving-flexible-lengths><span class=secno>4.2. </span> Resolving + Flexible Lengths</h3> - <li>Otherwise, if the value is a <length>, a <percentage>, or a - valid keyword, the <i>preferred size</i> is set to that value, the <a - href="#positive-flexibility"><i>positive flexibility</i></a> and the <a - href="#negative-flexibility"><i>negative flexibility</i></a> are set to - initial value (zero) + <p><a href="#flexible-length0"><i>Flexible lengths</i></a> are resolved + into normal, inflexible lengths by figuring out how large all of the <a + href="#flexible-length0"><i>flexible lengths</i></a> in the flexbox + <em>want</em> to be, then either adding or subtracting space from that + preferred size. The following algorithm normatively describes how to do + this conversion: - <li>Otherwise, the ‘<code class=css>flex()</code>’ function - is invalid. - </ul> + <ol> + <li> + <p>Determine the width and height of the flexbox itself.</p> - <dt>If the ‘<code class=css>flex()</code>’ function contains - two values: + <p class=issue>Figure out how to do this for all combinations of flexbox + direction, writing modes on the flexbox and flexbox items, and values of + "width" and "height".</p> - <dd> - <ul> - <li>If both values are non-negative numbers, the <a - href="#positive-flexibility"><i>positive flexibility</i></a> is set to - the first value, the <a href="#negative-flexibility"><i>negative - flexibility</i></a> is set to the second value, and the <i>preferred - size</i> is set to its initial value. + <p>The <a href="#main-size"><i>main size</i></a> of the flexbox's content + box is the <dfn id=available-space>available space</dfn>.</p> - <li>Otherwise, if one value is a non-negative number and the other is a - <length>, a <percentage>, or a valid keyword, the <a - href="#positive-flexibility"><i>positive flexibility</i></a> is set to - the number, the <a href="#negative-flexibility"><i>negative - flexibility</i></a> is set to ‘<code class=css>0</code>’, - and the <i>preferred size</i> is set to the other value. + <li>For each <a href="#flexbox-item"><i>flexbox item</i></a>, its <dfn + id=pre-flex-size title="pre-flex size|pre-flex sizes">pre-flex size</dfn> + is the <a href="#main-size"><i>main size</i></a> of the item's margin + box, honoring the ‘<code + class=css>min/max-width/height</code>’ properties. If the + ‘<code class=property>width</code>’ or ‘<code + class=property>height</code>’ properties are specified with <a + href="#flexible-length0"><i>flexible lengths</i></a>, do this calculation + as if they were instead specified with the <a + href="#flexible-length0"><i>flexible length's</i></a> <a + href="#preferred-size"><i>preferred size</i></a>. - <li>Otherwise, the ‘<code class=css>flex()</code>’ function - is invalid. - </ul> + <li> + <p>If the flexbox is <i>multi-line</i>, line-breaking must be performed.</p> - <dt>If the ‘<code class=css>flex()</code>’ function contains - three values: + <p>If the current line has more than one <a + href="#flexbox-item"><i>flexbox item</i></a> and the sum of all the <a + href="#pre-flex-size"><i>pre-flex sizes</i></a> of its <a + href="#flexbox-item"><i>flexbox items</i></a> is greater than the <a + href="#available-space"><i>available space</i></a>, a new line must be + created. The current line always contains the first <a + href="#flexbox-item"><i>flexbox item</i></a> within it, and as many + subsequent <a href="#flexbox-item"><i>flexbox items</i></a> as possible + while keeping the sum of <a href="#pre-flex-size"><i>pre-flex + sizes</i></a> less than the <a href="#available-space"><i>available + space</i></a>. The rest of the <a href="#flexbox-item"><i>flexbox + items</i></a> move to the next line, where this step is repeated as + necessary until no new lines are created.</p> - <dd> - <ul> - <li>If the first two values are non-negative numbers and the third value - is ‘<code class=css>0</code>’, the <a - href="#positive-flexibility"><i>positive flexibility</i></a> is set to - the first value, the <a href="#negative-flexibility"><i>negative - flexibility</i></a> is set to the second value, and the <i>preferred - size</i> is set to ‘<code class=css>0px</code>’. + <li> + <p>Within each line, run the following steps:</p> - <li>Otherwise, If two of the values are non-negative numbers, and the - other is a <length> (with a unit suffix), a <percentage>, or a - valid keyword, the <a href="#positive-flexibility"><i>positive - flexibility</i></a> is set to the first number, the <a - href="#negative-flexibility"><i>negative flexibility</i></a> is set to - the second number, and the <i>preferred size</i> is set to the other - value. + <ol> + <li>Subtract the sum of the <a href="#pre-flex-size"><i>pre-flex + sizes</i></a> of the <a href="#flexbox-item"><i>flexbox items</i></a> + on the line from the <a href="#available-space"><i>available + space</i></a>. This is the <dfn id=free-space>free space</dfn>. This + number may be negative, if the flexbox is single-line or a single <a + href="#flexbox-item"><i>flexbox item</i></a> is larger than the entire + flexbox. - <li>Otherwise, the ‘<code class=css>flex()</code>’ function - is invalid. - </ul> - </dl> + <li> + <dl> + <dt>If the <a href="#free-space"><i>free space</i></a> is zero: - <dl> - <dt>If the ‘<code class=css>flex()</code>’ function contains - less than one or more than three values: + <dd>All <a href="#flexible-length0"><i>flexible lengths</i></a> + resolve to their <a href="#preferred-size"><i>preferred size</i></a>. - <dd>The "flex()" function is invalid. - </dl> + <dt>If the <a href="#free-space"><i>free space</i></a> is positive: - <p class=issue>Note change from previous draft: default/unspecified are the - initial values: still ‘<code class=property>auto</code>’ for - width/height, 0 if it is ever applied to margins and padding; 0 for - positive flexibility (was 1 in previous draft). + <dd> + <p>Sum the <a href="#positive-flexibility"><i>positive + flexibility</i></a> of every <a href="#flexible-length0"><i>flexible + length</i></a> on the line. This is the <dfn + id=total-positive-flexibility>total positive flexibility</dfn>.</p> - <p class=note>Note that, while ‘<code class=css>0</code>’ - <length> is normally allowed to be specified without a unit suffix, in - flex() function it is ambiguous, as it is also an acceptable value for - flexibility. All ambiguous cases are resolved with preference to - flexibility, thus unitless "0" can only be applied to <i>preferred - size</i> when three vaues are specified and "0" is the last one. + <p>For each <a href="#flexible-length0"><i>flexible length</i></a>, + increment its <a href="#preferred-size"><i>preferred size</i></a> by + <code><a href="#free-space"><i>free space</i></a> * <pos-flex> / + <a href="#total-positive-flexibility"><i>total positive + flexibility</i></a></code>.</p> - <p>User agents that allow non-zero length values without unit suffix in - "quirks mode" may also accept a non-zero positive number as the - <i>preferred size</i> in pixels when in "quirks mode" and when it is the - third value in flex() function with three values. + <dt>If the <a href="#free-space"><i>free space</i></a> is negative: - <h3 id=flexible-margins><span class=secno>4.3. </span> Flexible margins and - paddings</h3> + <dd> + <p>Sum the <a href="#negative-flexibility"><i>negative + flexibility</i></a> of every <a href="#flexible-length0"><i>flexible + length</i></a> on the line. This is the <dfn + id=total-negative-flexibility>total negative flexibility</dfn>.</p> - <p>Paddings and margins are made flexible by setting their value to - ‘<code class=css>auto</code>’. + <p>For each <a href="#flexible-length0"><i>flexible length</i></a>, + increment its <a href="#preferred-size"><i>preferred size</i></a> by + <code><a href="#free-space"><i>free space</i></a> * <neg-flex> / + <a href="#total-negative-flexibility"><i>total negative + flexibility</i></a></code>. <span class=note>Note: since the free + space is negative, incrementing the preferred size by this number + makes the preferred size smaller.</span></p> + </dl> - <p>When margin or padding size on a <a href="#flexbox-item"><i>flexbox - item</i></a> is set to ‘<code class=css>auto</code>’ in - orientation of main axis, that margin or padding is included in flexbox - layout algorithm with flexibility of 1. + <li> + <p>Verify that min/max constraints aren't violated: for each <a + href="#flexbox-item"><i>flexbox item</i></a> on the line with + ‘<code class=property>width</code>’/‘<code + class=property>height</code>’ specified as a <a + href="#flexible-length0"><i>flexible length</i></a>, if instead + specifying the ‘<code + class=property>width</code>’/‘<code + class=property>height</code>’ as the <a + href="#preferred-size"><i>preferred size</i></a> would cause the item + to be in violation of its ‘<code + class=css>min/max-width/height</code>’ properties, resolve the + <a href="#flexible-length0"><i>flexible length</i></a> to the + smallest/largest length that would make it no longer in violation of + those properties, as defined by <a + href="http://www.w3.org/TR/CSS2/visudet.html#propdef-min-width">the + algorithm in CSS2.1</a>.</p> - <p>‘<code class=css>auto</code>’ margin can also be used for - alignment along the <i>cross-axis</i>, see ‘<a - href="#flex-align0"><code class=property>flex-align</code></a>’ - property. + <p>If any <a href="#flexbox-item"><i>flexbox item</i></a> was found to + be in violation by this step and resolved into an inflexible length, + reset the <a href="#preferred-size"><i>preferred size</i></a> of any + remaining <a href="#flexible-length0"><i>flexible lengths</i></a> to + their original values and restart this sub-algorithm.</p> - <p class=issue><a - href="http://wiki.csswg.org/spec/css3-flexbox#issue-15">(Issue 15)</a> - Interpretation of ‘<code class=property>auto</code>’ value for - margins parallel to <a href="#main-axis"><i>main axis</i></a>appears - incomplete because flex() doen't apply, and also margin/padding can't have - min/max values. Flex() could be allowed there, but it would be more - complicated. + <li>Any remaining <a href="#flexible-length0"><i>flexible + lengths</i></a> resolve to their <a href="#preferred-size"><i>preferred + size</i></a>. + </ol> + </ol> - <p class=issue>TODO: need solid use cases (and illustrations here) for - flexible margins and paddings. + <p>Once all <a href="#flexible-length0"><i>flexible lengths</i></a> have + been resolved, the ‘<a href="#flex-pack0"><code + class=property>flex-pack</code></a>’, ‘<a + href="#flex-align0"><code class=property>flex-align</code></a>’, and + ‘<a href="#propdef-flex-line-pack"><code + class=property>flex-line-pack</code></a>’ properties align the <a + href="#flexbox-item"><i>flexbox items</i></a> and the flexbox's lines + within the flexbox. <h2 id=flex-pack><span class=secno>5. </span> The ‘<a href="#flex-pack0"><code class=property>flex-pack</code></a>’ @@ -1094,9 +1128,10 @@ <p>Between and around the margins of <a href="#flexbox-item"><i>flexbox items</i></a> there are additional flexible lengths, called <dfn id=packing-space>packing space</dfn>. Packing space can absorb leftover - free space in a flexbox if there aren't any other <i>flexible length</i>s, - or if all the <i>flexible length</i>s have reached their maximum size. The - ‘<a href="#flex-pack0"><code + free space in a flexbox if there aren't any other <a + href="#flexible-length0"><i>flexible length</i></a>s, or if all the <a + href="#flexible-length0"><i>flexible length</i></a>s have reached their + maximum size. The ‘<a href="#flex-pack0"><code class=property>flex-pack</code></a>’ property defines the flexibility of these packing spaces: @@ -2031,6 +2066,9 @@ <li>The min/max/fit-content widths and heights of flexboxes in block contents + <li>Related to the above, ‘<code class=css>auto</code>’ + width/height of flexbox is shrink-to-fit. + <li>Other stuff? </ul> </div> @@ -2351,6 +2389,9 @@ <li>available free space, <a href="#available-free-space" title="available free space"><strong>8.</strong></a> + <li>available space, <a href="#available-space" title="available + space"><strong>4.2.</strong></a> + <li>baseline, <a href="#flex-align-baseline" title=baseline><strong>6.</strong></a> @@ -2401,6 +2442,16 @@ <li>flex-flow, <a href="#flex-flow0" title=flex-flow><strong>3.1.</strong></a> + <li>flexible length, <a href="#flexible-length" title="flexible + length"><strong>4.</strong></a>, <a href="#flexible-length0" + title="flexible length"><strong>4.1.</strong></a> + + <li>flexible lengths, <a href="#flexible-length0" title="flexible + lengths"><strong>4.1.</strong></a> + + <li>flexible length's, <a href="#flexible-length0" title="flexible + length's"><strong>4.1.</strong></a> + <li>flex-line-pack, <a href="#propdef-flex-line-pack" title=flex-line-pack><strong>7.1.</strong></a> @@ -2416,6 +2467,9 @@ <li>flex tuples, <a href="#flex-tuples" title="flex tuples"><strong>8.1.</strong></a> + <li>free space, <a href="#free-space" title="free + space"><strong>4.2.</strong></a> + <li>horizontal, <a href="#flex-flow-horizontal" title=horizontal><strong>3.1.</strong></a> @@ -2428,6 +2482,9 @@ <li>horizontal-rtl, <a href="#flex-flow-horizontal-rtl" title=horizontal-rtl><strong>3.1.</strong></a> + <li>hypothetical neighbors, <a href="#hypothetical-neighbors" + title="hypothetical neighbors"><strong>2.2.</strong></a> + <li>inner length, <a href="#inner-length" title="inner length"><strong>8.</strong></a> @@ -2461,9 +2518,15 @@ <li>positive flexibility, <a href="#positive-flexibility" title="positive flexibility"><strong>4.1.</strong></a> - <li>pre-flex size, <a href="#pre-flex-size" title="pre-flex + <li>preferred size, <a href="#preferred-size" title="preferred size"><strong>4.1.</strong></a> + <li>pre-flex size, <a href="#pre-flex-size" title="pre-flex + size"><strong>4.2.</strong></a> + + <li>pre-flex sizes, <a href="#pre-flex-size" title="pre-flex + sizes"><strong>4.2.</strong></a> + <li>relevant length, <a href="#relevant-length" title="relevant length"><strong>8.</strong></a> @@ -2480,6 +2543,12 @@ <li>total free space, <a href="#total-free-space" title="total free space"><strong>8.</strong></a> + <li>total negative flexibility, <a href="#total-negative-flexibility" + title="total negative flexibility"><strong>4.2.</strong></a> + + <li>total positive flexibility, <a href="#total-positive-flexibility" + title="total positive flexibility"><strong>4.2.</strong></a> + <li>vertical, <a href="#flex-flow-vertical" title=vertical><strong>3.1.</strong></a> Index: Overview.src.html =================================================================== RCS file: /sources/public/csswg/css3-flexbox/Overview.src.html,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- Overview.src.html 23 Aug 2011 17:46:39 -0000 1.40 +++ Overview.src.html 24 Aug 2011 23:09:48 -0000 1.41 @@ -110,8 +110,18 @@ <p>You can declare that an element is a flexbox, and thus should use flexbox layout, by setting the 'display' property on the element to the value 'flexbox' or 'inline-flexbox'.</p> <p>The ''flexbox'' value makes the flexbox act like a block in other layout modes. The ''inline-flexbox'' value makes the flexbox act like an inline-block in other layout modes.</p> - - <p>A flexbox establishes a new block formatting context for its content.</p> + + <p>Setting ''display:flexbox'' on an element forces it to use a new layout algorithm, and so some properties that were designed with the assumption of block layout don't make sense in a flexbox context. In particular:</p> + + <ul> + <li>all of the 'column-*' properties in the Multicol module compute to their initial values on a flexbox ('break-before', 'break-inside', and 'break-after' are still valid on a flexbox).</li> + + <li>'float' and 'clear' compute to their initial values on a flexbox item</li> + + <li>'vertical-align' has no effect on a flexbox item</li> + </ul> + + <p>A flexbox item creates a new flexbox formatting context for its contents. This is similar to a block formatting context: floats must not intrude into the flexbox, and the flexbox's margins do not collapse with any other margin. Additionally, all of the <i>flexbox items</i> establish new block formatting contexts for their contents.</p> <p class='issue'>Figure out the right terms to use here.</p> @@ -137,6 +147,9 @@ <!-- flexbox item: block-level child --> <div id="item1">block</div> + + <!-- not a flexbox item, because it's out-of-flow --> + <div id="not-an-item1.5" style="position: absolute;">block</div> <!-- flexbox item: block-level child --> <div id="item2" style="display:table">table</div> @@ -145,10 +158,10 @@ <div id="item3" style="display:table-cell">table-cell</div> <!-- flexbox item: anonymous block around inline content --> - anonymous item 4 + anonymous item 4 <!-- flexbox item: block-level child --> - <div id="item5">block</div> + <div id="item5">block</div> <!-- flexbox item: anonymous block around inline content --> anonymous item 6.1 @@ -168,27 +181,17 @@ <button id="item8">button</button> <!-- flexbox item: inline-table --> - <div id="item9" style="display:inline-table">table</div> + <div id="item9" style="display:inline-table">table</div> </div></pre> - <p>Notice that block element "not-an-item6.3" is not a separate flexbox item, because it is contained inside an inline element which is being wrapped into an anonymous flex item.</p> + <p>Notice that block element "not-an-item6.3" is not a separate flexbox item, because it is contained inside an inline element which is being wrapped into an anonymous flex item. Similarly, the block element "not-an-item1.5" is not a flexbox item, because it's absolutely positioned and thus out of flow.</p> </div> - <p>Out-of-flow elements like absolutely positioned elements leave behind a 'placeholder' inline element in their original position in the document <p class=issue>This needs to change. Placeholder is not fully hypothetical in this case, that element or line is detectable in "flex-pack:justify". TODO: define the "auto" position without a placeholder.</p> - - <p>Setting ''display:flexbox'' on an element forces it to use a new layout algorithm, and so some properties that were designed with the assumption of block layout don't make sense in a flexbox context. In particular:</p> - - <ul> - <li>all of the 'column-*' properties in the Multicol module compute to their initial values on a flexbox ('break-before', 'break-inside', and 'break-after' are still valid on a flexbox).</li> - - <li>'float' and 'clear' compute to their initial values on a flexbox item</li> - - <li>'vertical-align' has no effect on a flexbox item</li> - </ul> + <p>Absolutely positioned children of a flexbox are not <i>flexbox items</i>, but their "static position" (their position when the 'top'/'right'/'bottom'/'left' properties are ''auto'') responds somewhat to the flexbox's various properties. The element's static position in the flexbox's <i>cross axis</i> is on the <i>cross-start</i> edge of the flexbox's content box. The static position in the flexbox's <i>main axis</i> is slightly more complex to compute:</p> - <p class="issue">It has been proposed that vertical-align property applies to flex items (simliar to table cells). Decide if it makes sense, or if it should instead apply broader (to any blocks). </p> + <p>First, find the element's <dfn>hypothetical neighbors</dfn> by assuming that the element is a normal <i>flexbox item</i> with ''flex-order:1'', and reorder the flexbox's contents as mandated by 'flex-order'. The <i>flexbox items</i> immediately preceding and following (in the flexbox's direction) the element (if any) are the element's <i>hypothetical neighbors</i>.</p> - <p>A flexbox item creates a new BFC. The margins of a flexbox item do not collapse with any other margin. Flexboxes "shrinkwrap" their contents by default (when their 'width' or 'height' properties are ''auto''), similar to tables or floats.</p> + <p>If the element has two neighbors, its static position in the <i>main axis</i> is exactly in the center of the packing space between them when the flexbox is actually laid out. If the element has only a preceding neighbor, its static position in the <i>main axis</i> is flush with the <i>main-end</i> edge of the margin box of the neighbor. If the element has only a following neighbor, its static position in the <i>main axis</i> is flush with the <i>main-start</i> edge of the margin box of the neighbor. Finally, if the element has no neighbors (the flexbox has no in-flow children at all), the static position in the <i>main axis</i> is based on the value of 'flex-pack': if the value is ''start'' or ''distribute'', it's flush with the <i>main-start</i> edge of the flexbox's content box; if the value is ''end'', it's flush with the <i>main-end</i> edge of the flexbox's content box; if the value is ''center'', it's centered within the flexbox's content box.</p> <h2 id='ordering-orientation'> Ordering and Orientation</h2> @@ -391,97 +394,90 @@ <h2 id='flexibility'> Flexibility</h2> - <p>The defining aspect of flexbox layout is the ability to make various lengths of the <i>flexbox items</i> flexible. The 'width', 'height', 'padding', and 'margin' properties of a <i>flexbox item</i> can all be made flexible. Paddings and margins are made flexible by setting their value to ''auto'', while the width and height of a box can be controlled more precisely with the ''flex()'' function, defined below.</p> + <p>The defining aspect of flexbox layout is the ability to make the <i>flexbox items</i> "flex", altering their width or height to fill the available space. This is done by declaring a <dfn>flexible length</dfn> with the ''flex()'' function, defined below.</p> + + <p>Flexible lengths are composed of a (non-flexible) preferred size and a positive and negative flexibility. If there's free space left over in the flexbox after subtracting the preferred sizes of all the <i>flexbox items</i>, it is divided up among the <i>flexbox items</i> proportionally to their positive flexibility, making their width larger so they fill the space. Conversely, if the flexbox's size is <em>less</em> than the sum of the preferred sizes, so that the items would overflow normally, the <i>flexbox items</i> are shrunk proportionally to their negative flexibility, again so they exactly fit in the space.</p> <div class=example> <p class=issue>TODO: Examples!</p> </div> -<h3 id='resolving-flexible-lengths'> -Resolving Flexible Lengths</h3> - - <p>Flexbox layout resolves a <i>flexible length</i> into a definite length by first collecting all the lengths, flexible or inflexible, that will share some space. For example, for a horizontal flexbox, the lengths of the left and right margins, left and right borders, left and right paddings, and widths of all <i>flexbox items</i> share the width of the flexbox itself. Conversely, each <i title="flexbox item">flexbox item's</i> vertical margins, borders, padding, and height individually share the height of the flexbox.</p> - - <div class=figure> - <p class="caption issue">TODO: Diagram showing the relevant lengths in each axis.</p> - </div> - - <p>Flexbox layout then sums the <dfn>pre-flex size</dfn> of the lengths in each set. The <i>pre-flex size</i> of an inflexible length is just the length itself. The <i>pre-flex size</i> of a flexible length is its <i>preferred size</i>. If the sum of all the <i title="pre-flex size">pre-flex sizes</i> is less than the available width/height of the flexbox, then the difference is split up among all the <i title="flexible length">flexible lengths</i> with <dfn>positive flexibility</dfn>, with the space divvied up proportionally to the flexibility of each length. If the sum is greater than the available width/height, then all the <i title="flexible length">flexible lengths</i> with <dfn>negative flexibility</dfn> shrink in proportion to their flexibility to try and make the sum equal the available width/height.</p> - - <p>The 'flex-pack' and 'flex-align' properties offer additional options for free-space distribution. The precise details of how free space is determined and assigned to flexible lengths is detailed in a later chapter.</p> - - <h3 id='flex-function'> The ''flex()'' function</h3> - <p>The ''flex()'' function is used to specify the parameters of a <i>flexible length</i>: the <i title="positive flexibility">positive</i> and <i>negative flexibility</i>, and the <i>preferred size</i>. The syntax of the ''flex()'' function is roughly (see following prose for a precise description):</p> - - <pre class=prod>flex( [ <i title="positive flexibility"><pos-flex></i> || <!-- - --><i title="negative flexibility"><neg-flex></i> || <!-- - --><i title="preferred size"><preferred-size></i> ] )</pre> + <p>The ''flex()'' function is used to specify the parameters of a <dfn title="flexible length|flexible lengths|flexible length's">flexible length</dfn>: the <dfn id="positive-flexibility" title="positive flexibility">positive</dfn> and <dfn>negative flexibility</dfn>, and the <dfn>preferred size</dfn>. The syntax of the ''flex()'' function is:</p> - <p>Applicable to 'width' and 'height'</p> + <pre class=prod>flex( [ <pos-flex> <neg-flex>? ]? || <preferred-size>? )</pre> - <p class="note">In the future this may be applicable to margin and padding</p> + <p><code><pos-flex></code> and <code><neg-flex></code> are <code><integer>s</code>, while <code><preferred-size></code> is any value (other than another ''flex()'' function) that would be valid in the 'width' or 'height' property in which the function is used, except that zero lengths must not omit their unit.</p> - <dl> - <dt>If the ''flex()'' function contains a single value:</dt> - <dd> - <ul> - <li>If the value is a non-negative number, the <i>positive flexibility</i> is set to that value, the <i>negative flexibility</i> is set to ''0'', and the <i>preferred size</i> is set to the initial value of the property ('auto' for width and height).</li> + <p>The <code><pos-flex></code> component sets the length's <i>positive flexibility</i>; if omitted, the <i>positive flexibility</i> defaults to ''1''. The <code><neg-flex></code> component sets the length's <i>negative flexibility</i>; if omitted, it defaults to ''0''. The <code><preferred-size></code> component sets the length's <i>preferred size</i>; if omitted, it defaults to ''0px''.</p> - <li>Otherwise, if the value is a <length>, a <percentage>, or a valid keyword, the <i>preferred size</i> is set to that value, the <i>positive flexibility</i> and the <i>negative flexibility</i> are set to initial value (zero)</li> + <p class='issue'>Examples!</p> - <li>Otherwise, the ''flex()'' function is invalid.</li> - </ul> - </dd> - <dt>If the ''flex()'' function contains two values:</dt> - <dd> - <ul> - <li>If both values are non-negative numbers, the <i>positive flexibility</i> is set to the first value, the <i>negative flexibility</i> is set to the second value, and the <i>preferred size</i> is set to its initial value.</li> - - <li>Otherwise, if one value is a non-negative number and the other is a <length>, a <percentage>, or a valid keyword, the <i>positive flexibility</i> is set to the number, the <i>negative flexibility</i> is set to ''0'', and the <i>preferred size</i> is set to the other value.</li> +<h3 id='resolving-flexible-lengths'> +Resolving Flexible Lengths</h3> - <li>Otherwise, the ''flex()'' function is invalid.</li> - </ul> - </dd> + <p><i>Flexible lengths</i> are resolved into normal, inflexible lengths by figuring out how large all of the <i>flexible lengths</i> in the flexbox <em>want</em> to be, then either adding or subtracting space from that preferred size. The following algorithm normatively describes how to do this conversion:</p> - <dt>If the ''flex()'' function contains three values:</dt> - <dd> - <ul> - <li>If the first two values are non-negative numbers and the third value is ''0'', the <i>positive flexibility</i> is set to the first value, the <i>negative flexibility</i> is set to the second value, and the <i>preferred size</i> is set to ''0px''.</li> + <ol> + <li> + <p>Determine the width and height of the flexbox itself.</p> - <li>Otherwise, If two of the values are non-negative numbers, and the other is a <length> (with a unit suffix), a <percentage>, or a valid keyword, the <i>positive flexibility</i> is set to the first number, the <i>negative flexibility</i> is set to the second number, and the <i>preferred size</i> is set to the other value.</li> + <p class='issue'>Figure out how to do this for all combinations of flexbox direction, writing modes on the flexbox and flexbox items, and values of "width" and "height".</p> - <li>Otherwise, the ''flex()'' function is invalid.</li> - </ul> - </dl> + <p>The <i>main size</i> of the flexbox's content box is the <dfn>available space</dfn>.</p> + </li> - <dt>If the ''flex()'' function contains less than one or more than three values:</dt> - <dd>The "flex()" function is invalid.</dd> - </dl> - - <p class="issue">Note change from previous draft: default/unspecified are the initial values: still 'auto' for width/height, 0 if it is ever applied to margins and padding; 0 for positive flexibility (was 1 in previous draft).</p> + <li>For each <i>flexbox item</i>, its <dfn title="pre-flex size|pre-flex sizes">pre-flex size</dfn> is the <i>main size</i> of the item's margin box, honoring the 'min/max-width/height' properties. If the 'width' or 'height' properties are specified with <i>flexible lengths</i>, do this calculation as if they were instead specified with the <i>flexible length's</i> <i>preferred size</i>.</li> - <p class='note'>Note that, while ''0'' <length> is normally allowed to be specified without a unit suffix, in flex() function it is ambiguous, as it is also an acceptable value for flexibility. All ambiguous cases are resolved with preference to flexibility, thus unitless "0" can only be applied to <i>preferred size</i> when three vaues are specified and "0" is the last one.</p> + <li> + <p>If the flexbox is <i>multi-line</i>, line-breaking must be performed.</p> + + <p>If the current line has more than one <i>flexbox item</i> and the sum of all the <i>pre-flex sizes</i> of its <i>flexbox items</i> is greater than the <i>available space</i>, a new line must be created. The current line always contains the first <i>flexbox item</i> within it, and as many subsequent <i>flexbox items</i> as possible while keeping the sum of <i>pre-flex sizes</i> less than the <i>available space</i>. The rest of the <i>flexbox items</i> move to the next line, where this step is repeated as necessary until no new lines are created.</p> + </li> - <p>User agents that allow non-zero length values without unit suffix in "quirks mode" may also accept a non-zero positive number as the <i>preferred size</i> in pixels when in "quirks mode" and when it is the third value in flex() function with three values.</p> + <li> + <p>Within each line, run the following steps:</p> + + <ol> + <li>Subtract the sum of the <i>pre-flex sizes</i> of the <i>flexbox items</i> on the line from the <i>available space</i>. This is the <dfn>free space</dfn>. This number may be negative, if the flexbox is single-line or a single <i>flexbox item</i> is larger than the entire flexbox.</li> + <li> + <dl> + <dt>If the <i>free space</i> is zero:</dt> + <dd>All <i>flexible lengths</i> resolve to their <i>preferred size</i>.</dd> -<h3 id="flexible-margins"> -Flexible margins and paddings</h3> + <dt>If the <i>free space</i> is positive:</dt> + <dd> + <p>Sum the <i>positive flexibility</i> of every <i>flexible length</i> on the line. This is the <dfn>total positive flexibility</dfn>.</p> + + <p>For each <i>flexible length</i>, increment its <i>preferred size</i> by <code><i>free space</i> * <pos-flex> / <i>total positive flexibility</i></code>.</p> + </dd> - <p>Paddings and margins are made flexible by setting their value to ''auto''. </p> + <dt>If the <i>free space</i> is negative:</dt> + <dd> + <p>Sum the <i>negative flexibility</i> of every <i>flexible length</i> on the line. This is the <dfn>total negative flexibility</dfn>.</p> + + <p>For each <i>flexible length</i>, increment its <i>preferred size</i> by <code><i>free space</i> * <neg-flex> / <i>total negative flexibility</i></code>. <span class='note'>Note: since the free space is negative, incrementing the preferred size by this number makes the preferred size smaller.</span></p> + </dd> + </dl> + </li> - <p>When margin or padding size on a <i>flexbox item</i> is set to ''auto'' in orientation of main axis, that margin or padding is included in flexbox layout algorithm with flexibility of 1.</p> + <li> + <p>Verify that min/max constraints aren't violated: for each <i>flexbox item</i> on the line with 'width'/'height' specified as a <i>flexible length</i>, if instead specifying the 'width'/'height' as the <i>preferred size</i> would cause the item to be in violation of its 'min/max-width/height' properties, resolve the <i>flexible length</i> to the smallest/largest length that would make it no longer in violation of those properties, as defined by <a href="http://www.w3.org/TR/CSS2/visudet.html#propdef-min-width">the algorithm in CSS2.1</a>.</p> - <p>''auto'' margin can also be used for alignment along the <i>cross-axis</i>, see 'flex-align' property.</p> + <p>If any <i>flexbox item</i> was found to be in violation by this step and resolved into an inflexible length, reset the <i>preferred size</i> of any remaining <i>flexible lengths</i> to their original values and restart this sub-algorithm.</p> + </li> - <p class="issue"><a href="http://wiki.csswg.org/spec/css3-flexbox#issue-15">(Issue 15)</a> Interpretation of 'auto' value for margins parallel to <i>main axis</i>appears incomplete because flex() doen't apply, and also margin/padding can't have min/max values. Flex() could be allowed there, but it would be more complicated.</p> + <li>Any remaining <i>flexible lengths</i> resolve to their <i>preferred size</i>.</li> + </ol> + </li> + </ol> - <p class="issue">TODO: need solid use cases (and illustrations here) for flexible margins and paddings.</p> + <p>Once all <i>flexible lengths</i> have been resolved, the 'flex-pack', 'flex-align', and 'flex-line-pack' properties align the <i>flexbox items</i> and the flexbox's lines within the flexbox.</p> <h2 id='flex-pack'> @@ -1000,6 +996,7 @@ <h2 id="layout-interface"> Interface With Other Layout Algorithms</h2> + <div class=issue> <p>This section seems necessary, but not the precise way it's written. I need to identify precisely what data needs to be exposed both by the containing measure model (for the flexbox to use) and by the flexbox (for the containing measure model to use), and then write that up. Then the other measure models we produce can re-use the same template.</p> @@ -1008,6 +1005,8 @@ <ul> <li>The min/max/fit-content widths and heights of flexboxes in block contents</li> + <li>Related to the above, ''auto'' width/height of flexbox is shrink-to-fit.</li> + <li>Other stuff?</li> </ul> </div>
Received on Wednesday, 24 August 2011 23:09:54 UTC