W3C home > Mailing lists > Public > www-style@w3.org > June 2010

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

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 3 Jun 2010 09:16:33 -0700
Message-ID: <AANLkTilv2ayd7ajaeMZxEyQEGbBJKxK5aHVhb9ySRxAu@mail.gmail.com>
To: Andrew Fedoniouk <news@terrainformatica.com>
Cc: Brad Kemper <brad.kemper@gmail.com>, Zack Weinberg <zweinberg@mozilla.com>, www-style@w3.org
On Wed, Jun 2, 2010 at 9:03 PM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
>>> 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".

No, those definitions have been there since I first put this draft up
on the list two weeks ago.


>>> 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 />
> </div>
>
> What would be the width of div#A ?
> (#B there is just for illustration).

It's 700px, by the exact same logic in the previous version of this
problem.  (#B is 0px wide.)

It would be more useful if you could explain precisely which part of
my explanation wasn't useful.  There's something about this case that
you don't get, and my explanations aren't helping, so I'd like to know
why, just in case it's something I'm fundamentally missing.


>>> 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).

Where are you seeing that?  I never say anything like that anywhere in
my algorithm, nor in the more informal description of margin
collapsing in section 4; it's quite incorrect.


> 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.

A minimum size constraint is not a fixed length.  Nor do you use the
margin-collapse rules to calculate a width by itself.  Stop trying to
invent pieces of the algorithm that already exist and are strictly and
reasonably defined.  You're only confusing yourself.  If you're not
sure how something is calculated, just ask me and I'll explain it and
point to the place in my algorithm where it's defined.


>>> 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.
>
> ok.
>
>>
>>> 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.

There is no interpretation necessary.  All of those terms are
precisely defined.  (If you find an ambiguity, let me know.)


> 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.

That's tables.  This is flexbox.  You can *make* the preferred width
be the width of the content - either use "width: calc(fit-content +
1fl);" or (proposed, not yet in the draft) use "width: 1fla;".  Both
of these create a flexible width with flexibility 1 and preferred size
of the content's width.  It's just not the default way to do it.

You complained about the fact that the current flexbox draft makes
preferred width always equal to the width of the contents.  Why are
you now unhappy with the opposite?


>>> 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.

It might be different from XUL, I dunno.  It's not different from the
current flexbox draft, which would act in the exact same way.  That
is, given this markup:

<div width:1000px display:box>
  <div width:500px box-flex:1>some-500px-wide-text</div>
  <div width:700px box-flex:1>some-700px-wide-text</div>
</div>

The current flexbox draft would do the exact same thing that my
proposal does - the children would be shrunk to 400px and 600px wide,
respectively, and their contents would overflow.


> 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)

No, in Gecko's flex model (from the current draft, maybe not from XUL)
the <computed min width> is max(width, min-width) and the <computed
preferred width> is max(width, min-content).


> I am also using max (width, min-width, min-intrinsic)
> in flex blocks.
>
> Is it in principle possible in your model to define something
> like
>  width:calc(500px + 1fx) overflow:never?
> or in other words:
>  width:calc(500px + 1fx) min-width:min-intrinsic
> ? So that element will never overflow.

Yes, precisely the way you did it in the second example.  If you don't
want a box to shrink below a certain width, you use min-width - that's
the whole reason that property exists.


> Consider this HTML table sample:
>
> <table width="200" border=1>
>   <tr><td width="500">1</td>
>       <td width="300">2</td></tr>
>  </table>
>
> 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 6.5.2.3:
>>> "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.

I'm open to a different name.  I think you suggested "base length"
earlier, which is equally clear to me and has the advantage of being
substantially shorter.  Any other suggestions?

~TJ
Received on Thursday, 3 June 2010 16:17:26 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:28 GMT