You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-flexbox] Conflicting definitions of used cross size of a flex container #5190
https://drafts.csswg.org/css-flexbox/#algo-cross-container specifies the used cross size of a flex container, based on that of flex lines and therefore of flex items. However the container itself participates in an "outer" formatting context that typically also specifies a used size, with a different algorithm.
Note that this section overrides the rules that apply to calculating widths as described in section 10.3. In particular, if the margins of a table are set to '0' and the width to 'auto', the table will not automatically size to fill its containing block. However, once the calculated value of 'width' for the table is found (using the algorithms given below or, when appropriate, some other UA dependent algorithm) then the other parts of section 10.3 do apply.
I didn’t find anything similar in css-flexbox. Should it be added?
More generally, for elements that establish an independent formatting context it would be nice to have a common "protocol" for how the inner and outer layout modes interact with each other, in order to support arbitrary combination and not need separate definitions for each pair. (What happens for a grid item table? A table cell flex container?)
Yeah, looks like this rule pre-dates some of the more structured Sizing work, and isn't really correctly phrased: it only works for block and inline layout. Rewrote it to rely on the sizing rules of the formatting context in which the flex container participates (whatever those happen to be), and just provide a content-based size as input for when that's needed. (Grid already uses the correct text similar to this.)
dbc8f6d solves the conflict, but maybe not in the intended way.
For example, for a block-level column flex container, the cross size is the inline size and https://drafts.csswg.org/css2/visudet.html#blockwidth never uses a content-based size. width: auto is resolved as the containing block width minus margins etc.
Instead I think the intended behavior is that an auto or otherwise indefinite size is resolved as the sum of flex lines’ cross sizes, then the rest of the rules of the formatting context in which the flex container participates apply. Similar to tables in CSS 2.
it would be nice to have a common "protocol" for how the inner and outer layout modes interact with each other
Sketch of what this could look like, to avoid having everything "patch" block layout like css2-tables do and also properly fix #4905:
The outer formatting context determines available space for each of the two axes. This is typically the size properties if definite (adjusted for box-sizing and the min and max size properties), and indefinite values resolved in a layout-mode-specific way. One of the two components (but not both, I think?) may be infinite. For a horizontal block-level an indefinite width becomes the containing block minus margins etc, and an indefinite height infinite.
We "run layout" in an inner-layout-mode-specific way for the contents of a box (this ignores fragmentation), with the given available space. This results in a laid-out subtree and a used size in both axes. For a horizontal block container the used width is the available width (which is why CSS 2 conflated these two concepts), the used height is the available height if finite, content-based otherwise.
Then the outer formatting context positions the box based on the used sizes it receives as part of that result. For horizontal block-level this means solving the "outer width = containing block width" equation again, this time with the used width, and resolving margins accordingly.
In CSS2 the general model is roughly that width are in input decided by parents, and height is an output based on children. In the model above two-dimensional available space is an input, two-dimensional used size is an output. This is also more compatible with orthogonal flows (writing mode change).
The Flex Layout Algorithm is already written this way, I assume to avoid special-casing row v.s. column flex containers in many places. Adopting this everywhere would be good, but this is a more substantive change than we may want to do normatively within CSS2…
it would be nice to have a common "protocol" for how the inner and outer layout modes interact with each other
Agreed, and to a certain extent we're trying to do this by having each layout mode define its min-content and max-content sizes and size contributions, and having the specs for each formatting context reference those sizes of the items they are laying out.
p.s. sorry for the late response; we haven't triaged flexbox issues for far too long. :(
I’ll trust your judgment here. I haven’t been looking at Flexbox since not long after filing this so I don’t really have a mental model anymore of how these spec interactions work (and how I thought they ought to work)
Activity
[css-flexbox] Rewrote container cross-sizing to be generic to the for…
fantasai commentedon Jun 11, 2020
Yeah, looks like this rule pre-dates some of the more structured Sizing work, and isn't really correctly phrased: it only works for block and inline layout. Rewrote it to rely on the sizing rules of the formatting context in which the flex container participates (whatever those happen to be), and just provide a content-based size as input for when that's needed. (Grid already uses the correct text similar to this.)
Let us know if this addresses your concerns.
SimonSapin commentedon Jun 12, 2020
dbc8f6d solves the conflict, but maybe not in the intended way.
For example, for a block-level column flex container, the cross size is the inline size and https://drafts.csswg.org/css2/visudet.html#blockwidth never uses a content-based size.
width: autois resolved as the containing block width minus margins etc.Instead I think the intended behavior is that an
autoor otherwise indefinite size is resolved as the sum of flex lines’ cross sizes, then the rest of the rules of the formatting context in which the flex container participates apply. Similar to tables in CSS 2.SimonSapin commentedon Jun 12, 2020
Sketch of what this could look like, to avoid having everything "patch" block layout like css2-tables do and also properly fix #4905:
The outer formatting context determines available space for each of the two axes. This is typically the size properties if definite (adjusted for
box-sizingand the min and max size properties), and indefinite values resolved in a layout-mode-specific way. One of the two components (but not both, I think?) may be infinite. For a horizontal block-level an indefinite width becomes the containing block minus margins etc, and an indefinite height infinite.We "run layout" in an inner-layout-mode-specific way for the contents of a box (this ignores fragmentation), with the given available space. This results in a laid-out subtree and a used size in both axes. For a horizontal block container the used width is the available width (which is why CSS 2 conflated these two concepts), the used height is the available height if finite, content-based otherwise.
Then the outer formatting context positions the box based on the used sizes it receives as part of that result. For horizontal block-level this means solving the "outer width = containing block width" equation again, this time with the used width, and resolving margins accordingly.
In CSS2 the general model is roughly that width are in input decided by parents, and height is an output based on children. In the model above two-dimensional available space is an input, two-dimensional used size is an output. This is also more compatible with orthogonal flows (writing mode change).
The Flex Layout Algorithm is already written this way, I assume to avoid special-casing row v.s. column flex containers in many places. Adopting this everywhere would be good, but this is a more substantive change than we may want to do normatively within CSS2…
fantasai commentedon Jun 9, 2021
@SimonSapin Wrt #5190 (comment)
In-flow column flex containers do indeed resolve the cross size using https://drafts.csswg.org/css2/visudet.html#blockwidth same as block containers, and not like tables in CSS2. See testcase. So I think this is correct?
Agreed, and to a certain extent we're trying to do this by having each layout mode define its min-content and max-content sizes and size contributions, and having the specs for each formatting context reference those sizes of the items they are laying out.
p.s. sorry for the late response; we haven't triaged flexbox issues for far too long. :(
SimonSapin commentedon Jul 19, 2021
I’ll trust your judgment here. I haven’t been looking at Flexbox since not long after filing this so I don’t really have a mental model anymore of how these spec interactions work (and how I thought they ought to work)