Re: [css-flexbox] Fixing a mistake with flex-grow betwen 0 and 1

On Wed, Oct 9, 2013 at 8:03 AM, Daniel Holbert <dholbert@mozilla.com> wrote:
> On 10/07/2013 04:10 PM, Tab Atkins Jr. wrote:
>> In specific edits, this would just be a change in the
>> <http://dev.w3.org/csswg/css-flexbox/#resolve-flexible-lengths>
>> section - insert a step 2.5 that checks if the free space is positive
>> and the sum of the flex-grows are <1, and if so, sets all the flex
>> items to their hypothetical main size + the corresponding fraction of
>> the free space, then exits the algorithm.
>
> QUESTION 1:
> Why do this as "step 2.5"?  I'd think that Step 5 ("Distribute free
> space proportional to the flex factors") would be the obvious place to
> make this tweak. (just changing the ratio that we use, if the sum of the
> flex-grow factors is < 1, but otherwise doing everything normally)

Because I don't want it to be part of the cycling, and exiting as soon
as possible seemed appropriate.  Exact placement can be tweaked,
though.

> QUESTION 2:
> Why exit the algorithm? I'd expect that we'd need to proceed with the
> "Fix min/max violations" and continue cycling as appropriate.
> Otherwise, we'd never discover min/max violations, and we'd end up with
> elements sized too small or too large for those constraints.
> (If instead we moved this logic to be in Step 5, as suggested above, and
> dropped the "exit", then I think we'd honor the constraints correctly...)

Right, I accidentally forgot to include the "fix min/max violations"
part, and then forgot to reply to the thread saying I'd forgotten it.
^_^

I had another response written here, but I deleted it because I
managed to convince myself of the opposite conclusion that I set out
with.  ^_^  Okay, so I think we can avoid discontinuities by slightly
rewriting the flex distribution algo:

1. Initially each flexible element claims an amount of *desired free
space* proportional to its flex.  A flex of 1 means "all the free
space", a flex of 2 means "twice the free space", a flex of .5 means
"half the free space". This initial claim of free space is maintained
throughout the algorithm as the *originally desired free space*.

2. Loop:
  2.1. If the sum of desired free space is greater than the actual
free space, normalize all the desired free spaces so that the sum
equals the total.
  2.2. Fix min/max violations, freezing the violators and reducing the
actual free space accordingly.  If there were no violations, exit the
loop.
  2.3. Of the remaining unfrozen items, reset their desired free space
to their originally desired free space.  Return to the beginning of
the loop.

3. Set each element's main size to its preferred main size + its
desired free space.


This means that an element with flex:.2 will *always* claim 20% of the
free space, unless other elements end up claiming too much.  Example:

<div style="display: flex; width: 100px;">
  <div style="flex: .2;"></div>
  <div style="flex: .2; max-width: 10px;"></div>
</div>

We'll run flexing, setting both to 20px.  Fix the max violation.  Re
run flexing, still setting the first to 20px.  Done.  This is
continuous up through 5 element with the same flex.  Heck, you can
have *8* copies of the second div (all claiming 10px of space), and
the first element will sit there with a size of 20px the whole time.
When you bump it to 9 constrained items, it'll finally shrink to 10px,
as desired.  This seems like it avoids the continuity problems.

Similarly, if you increase the flex of the second item, the first will
remain 20px the whole time.  There's no discontinuity as the second
item cross flex:.8.

This algorithm should be identical to the current flexing algorithm
when all the items have a flex of 1+, or when the non-violating items
in the final cycle have a sum of flexes 1+.

~TJ

Received on Wednesday, 9 October 2013 17:59:49 UTC