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

From: "Tab Atkins Jr." <>
Sent: Wednesday, June 02, 2010 4:51 PM
To: "Andrew Fedoniouk" <>
Cc: "Brad Kemper" <>; "Zack Weinberg" 
<>; <>
Subject: Re: [css3-flex] calc(flex) and concept of free space.

> On Tue, Jun 1, 2010 at 7:47 PM, Andrew Fedoniouk
> <> wrote:
>> --------------------------------------------------
>> From: "Tab Atkins Jr." <>
>> Sent: Monday, May 31, 2010 10:53 PM
>> To: "Andrew Fedoniouk" <>
>> Cc: "Brad Kemper" <>; "Zack Weinberg"
>> <>; <>
>> Subject: Re: [css3-flex] calc(flex) and concept of free space.
>>> On Mon, May 31, 2010 at 8:26 PM, Andrew Fedoniouk
>>> <> wrote:
>>>> Terribly sorry. Forgot to add box-sizing:border-box there.
>>>> So the question looks like:
>>>> <div width:1000px padding-left:1fx box-sizing:border-box>
>>>>  <div width:calc(500px + 1fx) />
>>>> </div>
>>>> What would be the width of inner div?
>>>> In other words what exactly that preferred width means?
>>> (Assuming that the outer div is a flexbox, but not a child of another
>>> flexbox.)
>>> The inner div is 500px.  Read section 6.2 of my proposal for the
>>> precise details.  The outer div's flex gets distributed in the first
>>> round, the child's flex is distributed in the second round.  When
>>> distributing space, you compute free space by looking at the "preflex
>>> lengths" of the children.  That's 500px in this case, so there's 500px
>>> of free space that the outer div's padding can soak up.
>> There are terms "preflex length" and "relevant preflex length"
>> but they were not defined anywhere.
> Dude, the definitions are right there at the bottoms of section 6.1 and 
> 6.2..

Just for the record: that sentence of mine is using Past Tense.
At the moment of initial writing it used to be no definition
of "preflex length".

>> So is my question. Here we have two layers of flexes, outer
>> flex padding-left:1fx, width:1fx and inner flex
>> inside, that calc(700px + 1fx):
>> <div width:1000px padding-left:1fx box-sizing:border-box>
>>  <div width:calc(700px + 1fx) />
>> </div>
>> While computing free space in outer div we need to know
>> "width of the flexbox content". In this case it is a sole element:
>>  <div width:calc(700px + 1fx) />
>> As far as I understand your document the final result of
>> calc(700px + 1fx) calculation is not known at the moment
>> of outer layer calculations - it will be computed later when
>> inner layer will have box width to distribute its flexes.
>> So I suspect inner div will get 500px, right?
> No, I already answered this precise question.
> While the used length of the inner <div> isn't known yet (it has to
> wait until the second distribution round, section 6.3), the *preflex
> length* is what we care about, and that's known.  The preflex length
> is 700px (the greater of the minimum size (0px) and the preferred size
> (700px)).  So the padding on the outer div will get 300px, and the
> inner div will be 700px wide.

Seems like my question was not clear enough.
Let me put it this way:

<div width:1000px padding-left:1fx
         box-sizing:border-box *flow:vertical*>
  <div #A width:calc(700px + 1fx) />
  <div #B width:2fx />

What would be the width of div#A ?
(#B there is just for illustration).

>> Consider these samples:
>> a)
>> <div width:1000px flow:horizontal >
>>  <div width:calc(200px + 1fx) />
>>  <div width:calc(400px + 1fx) />
>> </div>
> Free space is 400px.  This is split evenly and added to the preferred
> widths.  The first child ends up 400px wide, the second is 600px wide.
>> b)
>> <div width:1000px flow:horizontal >
>>  <div min-width: 200px width: 1fx />
>>  <div min-width: 400px width: 1fx />
>> </div>
> Ooh, that exposes a bug in my algo.  Section 6.5 *should* say "This
> must be equal to the total length minus the sum of all the
> **preferred** lengths in the set of lengths.".  I've fixed it now.
> In that case, free space is 1000px.  It's split evenly and added to
> the preferred width of each child (which is 0 for both in this case).
> So both end up as 500px.

Ok, but it is still a problem even if you will fix that.

Reading definition of the "preflex length":

"The preflex size of a flexible length is the greater of the flexible
length's minimum and preferred sizes."

E.g. for two collapsed margins you say that this margin
is using max(fixed-length, preferred-length).

Width, as an entity, here:

  min-width: 400px width: 1fx

has also fixed part - 400px and preferred part (that is zero here)
max( 400px, 0 ) gives us 400px.

So according to your document cases a) and b) shall produce
the same result.

Or you should define "flexible length's minimum"
for width/height properties.

>> c)
>> <div width:1000px flow:horizontal >
>>  <div width:calc(200px + 1fx) min-width:200px />
>>  <div width:calc(400px + 1fx) min-width:400px />
>> </div>
> Same as A.


>> d)
>> <div width:1000px flow:horizontal >
>>  <div width: 1fx >some-200px-wide-text</div>
>>  <div width: 1fx >some-400px-wide-text</div>
>> </div>
> Rendering is same as B in this case, but may be different if the
> parent's width is smaller, as this has no min-width constraints.
>> e)
>> <div width:1000px flow:horizontal >
>>  <div width: 1fx >some-500px-wide-text</div>
>>  <div width: 1fx >some-700px-wide-text</div>
>> </div>
> Same as D.  (The contents of the second child overflow.)

This test is also about interpretation of "flexible length's minimum"
"preferred length" and "preflex length" that you use.

So by default width of element content is not its
preferred width. Probably it is better then to use
something like "base width" rather than "preferred width"?

In tables for example, preferred width of a column is
a content width of cells in it.

>> f)
>> <div width:1000px flow:horizontal >
>>  <div width:calc(500px + 1fx) >some-500px-wide-text</div>
>>  <div width:calc(700px + 1fx) >some-700px-wide-text</div>
>> </div>
> Free space is -200px.  This gets split evenly and added to the
> preferred width of each.  The first child ends up as 400px wide, the
> second child as 600px wide.  The contents of both overflow.

So your vision of display:box tends to follow
display:block rules rather than BFC blocks like display:table-cell.
Seems like your point of view is different from what Gecko/XUL
is using.

E.g. in
  display:table-cell element (and in Gecko flex model, AFAIU):
  <computed min width> is max (width, min-width, min-intrinsic)
in display:block elements
    <computed min width> is max (width, min-width)

I am also using max (width, min-width, min-intrinsic)
in flex blocks.

Is it in principle possible in your model to define something
  width:calc(500px + 1fx) overflow:never?
or in other words:
  width:calc(500px + 1fx) min-width:min-intrinsic
? So that element will never overflow.

Consider this HTML table sample:

<table width="200" border=1>
    <tr><td width="500">1</td>
        <td width="300">2</td></tr>

You can think of cells there as blocks defined this way:

 width:calc(500px + 1fx)
 width:calc(300px + 1fx)

But cells there are strict BFCs.

>> And yet about
>> "Add this free space to the preferred size of every
>> flexible length"
>> What is the preferred size of this element:
>> <div width: 1fx >some-500px-wide-text</div>
>> zero or 500px?
> 0.

This is why I don't like "preferred" as a name of this
entity. Or we just use different systems of preferences.

Andrew Fedoniouk


Received on Thursday, 3 June 2010 04:03:42 UTC