Re: [css3-flex] calc(flex) and concept of free space.

On Fri, May 28, 2010 at 8:34 PM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
> It seems that I am the only person so far who have implemented
> flex units as a complete system. I mean I have infrastructure already in
> place to try the calc() in real environment. So here are practical
> questions.
>
> 1) Meaning of "free space".
>
> I am assuming that free space gets computed as:
> container-inner-space - sum-of-min-widths-of-children.
> So if  sum-of-min-widths-of-children is greater than
> container-inner-space then
> 1.a) there is no free space, free space is zero;
> 1.b) there is a free space but it is negative, if "yes"
>   then it is not a free space strictly speaking.
>   Good name for it anyone?
>
> Anyway, which one of 1.a) and 1.b) is true?

1b.  This is in step 6.5.1 of my proposal.


> 2) Meaning of calc(flex + fixed)
>
> Let's imagine that we have container with
> inner width = 1000px that has single empty child A
> so it has no intrinsic min/max-widths.
>
> -----------------------------------------------------------------
> If that A element is defined as
>
> A { width: calc(100px + 1fx); }
>
> I assume that min-widths-of-children in this case is:
>
> 2.a) min-width = 100px, free-space = 900px.
>
> So its computed width is just 1000px ?
>
> So that definition above is exactly (A - single child)
> A { width: 1fx; min-width: 100px; }
>
> Yes/no?

No.  The calc() expression does not set a minimum size, it sets a
preferred size.  The flexible length can get smaller than the
preferred size if necessary.  In particular, if the parent was only
50px, then the child would also be 50px.  (If you had set min-width
like in your last paragraph, the child would still be 100px.)

Setting a preferred size on the only flexible length in that axis
basically does nothing (like setting 2fl versus 1fl in that situation
- there's no difference).


> -----------------------------------------------------------------
> If A element is defined as
>
> A { width: calc(1100px + 1fx); }
>
> 2.b) min-width = 1100px, free-space = -100px so element
>  will not overflow as total width = 1000px;
> 2.c) min-width = 1100px, free-space = 0px and element
>  will overflow;
>
> If 2.c is true then it means that free-space as a value
> cannot be negative.

Neither, as stated.  The length's minimum size is still 0, since there
is no min-width set and no max() expression wrapping it.

The free space is -100px, and so the child will shrink to 1000px wide
and not overflow.  (This is your 2b, just with correct details.)


> -----------------------------------------------------------------
> Now let's add min-width constraints in our equations
> A
> {
>  width: calc(100px + 1fx);
>  min-width: 900px;
> }
>
> 2.d)
>  min-width = 900px,
>  free-space = 100px and
>  width = 900px.
> 2.e)
>  min-width = 900px + 100px,
>  free-space = 0px and
>  width = 1000px.

I'm not sure why you keep using "min-width" in this way.  The way in
which you're using it now doesn't even make sense.  Do you mean
something different than the "min-width" property in CSS?  If so, it
would be helpful if you used a different term.  I specifically use
"minimum size" for that purpose.

In any case, the free space is 100px (1000px - 900px), which gets
distributed to the child, so the child is 1000px wide.  So neither of
your cases is true.


> -----------------------------------------------------------------
> Here is over constrained case
> A
> {
>  width: calc(100px + 1fx);
>  min-width: 1100px;
> }
>
> 2.f)
>  min-width = 1100px,
>  free-space =0px and
>  width = 1100px,
> 2.g)
>  min-width = 1100px,
>  free-space = -100px and
>  width = 1000px.
>
> If 2.g then it means that element dimensions can
> be less than its min constraints.
> If 2.f then it means, again, free-space cannot be negative.

The element can't go below 1100px, because of its min-width.  So 2f.

I have no idea what you mean by "free-space cannot be negative".  This
example demonstrates nothing of the sort.  Let's walk through the
algorithm in 6.5.

Step 1: Free space is 1000px - 1100px, so -100px.
Step 2: Free space is negative, skip this step.
Step 3.1: Total flex is 1.
Step 3.2: The child gets all the reduction, and so must be shrunk by 100px.
Step 3.3: The child's width is now 0px (100px preferred size - 100px reduction).
Step 3.4: The child's width is in violation of its minimum size
constraint, so it gets set to the minimum size and made inflexible.
(Child is now 1100px wide.)  Algorithm starts over.

Step 1: Free space is -100px.
Step 2: Free space is negative, skip this step.
Step 3.1: Total flex is 0, so nothing can be distributed.  Algorithm is done.


> -----------------------------------------------------------------
> Here is one more, but with max-width constrain
> A
> {
>  width: calc(300px + 1fx);
>  max-width: 200px;
> }
>
> What is the value of free space for the need of flex calculations?
>
> 2.h) 1000px - 300px = 700px?
> 2.i) 1000px - 200px = 800px?

Free space is 700px.  You subtract the "preflex length" of the
flexible length.  That is defined as the greater of the minimum and
preferred size.

I know that I overlooked the case where the maximum size is less than
the preflex length.  I might want to revise the definition of preflex
length to take that into account.  I'll have to work through some
examples to see if that's necessary.


> -----------------------------------------------------------------
> Consider these two elements in the same 1000px container:
>
> A {   width: calc(700px + 1fx); }
> B {   width: calc(500px + 1fx); }
>
> what would be their computed widths?
> I assume that:
> 2.j)  700px and 500px

The calc()s aren't yet resolved at computed-value time.


> so again free space is non-negative.

I have no idea what this means.  Even if we did say that their widths
were 700px and 500px, the free space would be -200px.


> of the are
> 2.k) 583px and 417px and so we are getting
> XUL's additive logic here?

Where are you getting these numbers from?  The *used* values of the
widths of these two elements are 600px and 400px.  There was -200px of
free space, and they have equal flex, so they shrink an equal amount.


> -----------------------------------------------------------------
>
> So if to assume that free space is always non-negative
> that leads us to the constatation of the following:
> any expression with flex units can only increase
> minimal value and never decrease.

Free space can obviously be negative, and I have absolutely no idea
how you are coming to this conclusion.  It doesn't follow from
anything you or I have said this entire time.  Every time you say
"free-space can't be negative" in this email it appears to be a
non-sequitur, unconnected to anything that came before or after.


> So constructions like calc( 20px - 1fx) shall be prohibited.

Those constructions should be prohibited in any case; this has
absolutely nothing to do with whether free space is negative or not.
A negative flex has no effect.  I'm not yet sure whether I should say
that it's a parse error when it can be determined at parse time, or
just say that it's always identical to 0fl.

~TJ

Received on Saturday, 29 May 2010 16:23:05 UTC