Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-flexbox] Conflicting definitions of used cross size of a flex container #5190

Closed
SimonSapin opened this issue Jun 10, 2020 · 5 comments
Closed
Labels
Closed Accepted as Obvious Bugfix Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-flexbox-1

Comments

@SimonSapin
Copy link
Contributor

@SimonSapin SimonSapin commented Jun 10, 2020

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.

For example, for a block-level horizontal column flex container, the cross size is the width and https://drafts.csswg.org/css2/visudet.html#blockwidth applies.

For comparison, tables in CSS 2 have normative text specifically about resolving this conflict: https://drafts.csswg.org/css2/tables.html#width-layout

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

tabatkins added a commit that referenced this issue Jun 11, 2020
…matting context, rather than assuming block layout. #5190.
@fantasai
Copy link
Collaborator

@fantasai fantasai commented 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
Copy link
Contributor Author

@SimonSapin SimonSapin commented 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: 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.

@SimonSapin
Copy link
Contributor Author

@SimonSapin SimonSapin commented Jun 12, 2020

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:

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

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

  3. 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
Copy link
Collaborator

@fantasai fantasai commented 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?

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

@SimonSapin
Copy link
Contributor Author

@SimonSapin SimonSapin commented Jul 19, 2021

So I think this is correct?

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)

@tabatkins tabatkins added the Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. label Aug 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted as Obvious Bugfix Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-flexbox-1
Projects
None yet
Development

No branches or pull requests

3 participants