Re: [css-flexbox] Behaviour of percentage heights in column direction

On 21 June 2014 00:27, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> On Fri, Jun 20, 2014 at 2:08 PM, Greg Whitworth <gwhit@microsoft.com> wrote:
>>> Tab thought that Chrome was doing the right thing here, but I have to say I
>>> much prefer the Firefox/IE behaviour. It seems very useful to be able to
>>> specify an explicit height on the root element of a widget, then use nested
>>> flexboxes within it and have everything flow down the layout hierarchy
>>> appropriately. Particularly, if you can't do this with an element whose height
>>> is controlled only by its "flex"
>>> property, then there are certain layouts that will be impossible (although grid
>>> might cover them).
>>
>> I think that Chrome is not doing the right thing here. The spec for flex basis states the following [1]:
>>
>>     # The flex basis is resolved the same way as ‘width’ in horizontal writing modes [CSS21]: percentage values of ‘flex-basis’ are resolved against the flex item’s containing block,
>>     # i.e. its flex container, and if that containing block’s size is indefinite, the result is the same as a main size of ‘auto’.
>>     # Similarly, ‘flex-basis’ determines the size of the content box, unless otherwise specified such as by ‘box-sizing’ [CSS3UI].
>>
>> In your example all of the flex containers have a flex-direction of column so the "width" in the above statement is actually the height of the items. Also since we know that the height of the container is not indefinite those percentages should be resolved. I have simplified your example down to just one flex example so it is easier to see the problem in the Blink engine [2].
>
> Why aren't they indefinite?
>

At least for the example in the jsfiddle that Greg posted, I believe
they aren't. My reasoning is as follows:

1. The height of item1 and item2 will resolve if the height of their
parent, flex-child, is definite.
2. The height of flex-child is definite if it can be determined
without measuring its content.
3. flex-child has a flex basis of 50%
4. flex-child's parent, flex-root, has a definite height of 600px.
5. Since a percentage of a definite value is definite, and height is
the main axis for flex-root, flex-child therefore has a definite flex
basis of 50% * 600px = 300px
6. According to the line length determination algorithm, flex-child's
flex base size should therefore equal its flex basis.
7. Since flex-child has no other min and max size constraints, its
hypothetical main size should equal its flex basis, which equals its
definite flex basis.
8. Since flex-root is a single line container, its children, which
only consists of flex-child, must be collected on one line.
9. The used main size of flex-child must be determined by resolving
its flexible length.
Using the CR algorithm:
10. Since the sum of the hypothetical main sizes (300px) is smaller
than the container's inner main size (600px), the flex grow factor
will be used.
11. Since flex-child has no explicit value for flew-grow, it will default to 0.
12. Since its flex factor is 0, flex-child will be frozen, meaning its
target main size will equal its hypothetical main size (300px)
14. Since there are no flexible items, the algorithm loop will exit immediately.
15. flex-child's main size should be set to its target main size.

Since the main size of flex-child has been determined without
measuring its children, their percentage/flex-basis heights can safely
be resolved to a percentage of it.

Things get trickier when you have items without a set flex basis that
can  grow and shrink, which is why I produced the other testcases. My
reading of the algorithms in the spec is that there is no way to size
items that don't have a definite flex basis without measuring their
content. *However* the spec also says that other algorithms that
produce the same results are acceptable. It's possible to conceive of
algorithms that do not measure content when it can be determined that
it will have no effect on the resulting size, such as when there is
only a single flexible item within a flex container with a definite
main size.

Such an algorithm would produce the same results, in terms of the
sizes of its children, but would do so in way that makes them
definite. Would that be enough to make the algorithm nonconforming?
It's a bit of a weird situation.

I think the answer is that both Chrome and Firefox/IE are partly
wrong: Chrome should treat flex items with a percentage flex basis in
a definitely sized container as having a definite size. Firefox/IE
should treat flex items that don't match those conditions as having an
indefinite size.

Jon

> ~TJ

Received on Saturday, 21 June 2014 02:02:42 UTC