Re: Fw: RE: [css-flexbox] Summary of planned changes to Flexbox Module

--------------------------------------------------
From: "Tab Atkins Jr." <jackalmage@gmail.com>
Sent: Thursday, May 13, 2010 5:55 PM
To: <robert@ocallahan.org>
Cc: "Alex Mogilevsky" <alexmog@microsoft.com>; "Adam Del Vecchio" 
<adam.delvecchio@go-techo.com>; <www-style@w3.org>
Subject: Re: Fw: RE: [css-flexbox] Summary of planned changes to Flexbox 
Module

> Well, turns out the algorithm for calculating flexes is remarkably easy.
>
> All of this takes place during used-width calculation, after computed
> lengths have been computed.  This algorithm is written in terms of
> width, but can be used for either dimension with no change, since all
> width/height dependent calculations happen before flexes are computed,
> so we can be totally direction-agnostic in the algo.
>
> 0) Resolve all non-flexible lengths on the flexbox, and all non-auto,
> non-flexible lengths on the flexbox children.
>   Note that flex units are allowed in the padding of flexboxes even
> if they are, themselves, in block flow or similar, rather than nested
> inside of another flexbox.  For the purpose of this step, a flex unit
> appearing in padding of the flexbox is treated as 0..
>   (That is, given "<div display:block;><div display:flexbox;
> padding:0 1fl;><span width=50%></span></div></div>", the inner div's
> padding is treated as 0 for the purpose of determining its width in
> the normal flow of its parent, and also for resolving the 50% width on
> the span.)
>   (I need to go into somewhat more detail here, to specify what the
> min/max/fit-content width and height of a flexbox are.  It's a
> relatively simple calculation - "as normal, but treat all flex units
> as 0".)
>
> 1) Convert 'auto' widths and margins on flexbox children:
>  a) If width is 'auto' and padding-left, padding-right, margin-left,
> and margin-right are all not 'auto' and not flexible, the width is
> treated as "1fl" for the purposes of this algorithm.
>  b) Otherwise, if width is 'auto' it is treated as "fit-content", and
> padding/margin-left/right values that are 'auto' are treated as "1fl"
> for the purposes of this algorithm.
>
> 2) Collapse margins on flexbox children, if that margin is collapsible
> (dependent on value of margin-collapse):
>  a) Separate each margin into a flexible segment and an inflexible
> segment (many margins will have only one or the other - in that case,
> the missing segment is zero).

I suspect that it is better to use "fixed/flexible part" instead of
"fixed/flexible segment".

>  b) The collapsed margin is then composed of 3 segments: an
> inflexible segment, a flexible segment, and a flexible segment with a
> minimum-size constraint:

It is not clear what does "margin is then composed of 3 segments"
mean.  Value of collapsed margin may have fixed part or/and
flex part. Where the "3" comes from?

>    i) The inflexible segment is the minimum of the two inflexible segments
>    ii) The flexible segment is the minimum of the two flexible segments
>    iii) The flexible-with-constraint segment has flex equal to the
> difference of the two flexible segments, and a minimum-size constraint
> equal to the difference of the two inflexible segments

This is not clear at all. You have two margins (m1 and m2) that are 
collapsed
into single space m.

If m1 is flex and m2 is flex then m is a flex of max(m1,m2)
If m1 is fixed and m2 is fixed then m is a fixed value of max(m1,m2)
Otherwise you have so called "discriminated flex value" -
flex with min constraint.

>
> 3) You now have a collection of flexible segments, some with
> minimum-size or maximum-size constraints (min-width and max-width
> specify constraints on the width's flexibility, if any), and a
> collection of inflexible segments (any non-flexing widths, paddings,
> margins, and borders).  The free space in the flexbox is equal to the
> width of the flexbox minus the length of all the inflexible segments
> and the minimum width of any flexible segments with a minimum-size
> constraint.  If the free space is negative, set all flexible segments
> to 0 length and exit this algorithm; the children will overflow the
> flexbox in the direction indicated by box-begin.
>
> 4) If the flexbox is in a flow that does not allow flex units, but it
> has flexible padding, distribute the free space among the flexbox's
> padding in proportion with the flexibility of padding-left/right.
> Reduce the free space by the amount of flex the padding has assumed.
>   (If the flexbox is in a flow that allows flex units, then flexible
> padding or any other flexible unit has already been resolved when
> doing the flex computations of its parent, and so this step is
> unnecessary.)

This is not clear. I suspect that this paragraph will ruin floats.
Could you provide any example of this?

>
> 5) Distribute flex among flexbox children:
>  a) Divide the free space up among the flexible segments in
> proportion to their flexibility.
>  b) If any minimum-size or maximum-size constraints are not
> satisfied, set that segment to the minimum size necessary to satisfy a
> minimum-size constraint, or the maximum size necessary to satisfy a
> maximum-size constraint, and set that segment's flexibility to 0.
> Return to step (a).
>  c) If all constraints are satisfied, the algorithm is finished.
>
>
> This algorithm does involve iterating until the flexibility
> constraints are satisfied, but this should be acceptable.  The current
> Flexbox spec requires the exact same iteration, and further, this
> isn't iterative *layout*, since all the inflexible lengths the
> algorithm needs can be calculated before this is run, and the layout
> needs of grandchildren of flexboxes won't affect the variables that
> this algo cares about.
>
> I suspect linear programming may lead to a faster calculation of flex
> distribution, but I don't know the subject well enough to say anything
> about that.

Usually linear programming tasks are being solved by various
iterative algorithms, simplex method as an example.

But this particular way of flex computation that you've defined
is finite. The loop you have described above is limited by
a number close to N*ln(N) repetitions with very good
convergence. In most cases it is just N so nothing to write
home about.

>
> It's important to note where flex units are allowed here.  Children of
> flexboxes may use flex units in any of width/height/margin/padding.

I suggest to add there border-width too. Think about border-image's,
e.g. gradients.

> Flexboxes themselves, if they are not in a flow that allows flex
> units, may still use flex units in their padding only.  (If they are
> in a flow that allows flex units, such as if they are themself the
> child of another flexbox, then they may of course use flexes for any
> of the dimensions allowed by that flow.)
>
> Does anyone see any problems?  Any places where you think I've missed
> an important case?  Any particular area you'd like to see in more
> detail?
>

It is better to move definition of the algorithm to separate chapter.
The algorithm takes vector of triplets {min, max, flex} and total length to 
distribute
and computes final lengths for each element in the vector.
How is that vector gets filled is irrelevant to the algorithm per se.
This algorithm is used all over CSS already. In 'auto' calculations in most 
of cases
and in <table> layout computations.

-- 
Andrew Fedoniouk

http://terrainformatica.com



 

Received on Friday, 14 May 2010 07:09:43 UTC