Skip to content

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

Closed

Description

@SimonSapin

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

Activity

  1. fantasai commented on Jun 11, 2020

    @fantasai
    Collaborator

    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.

  2. SimonSapin commented on Jun 12, 2020

    @SimonSapin
    ContributorAuthor

    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.

  3. SimonSapin commented on Jun 12, 2020

    @SimonSapin
    ContributorAuthor

    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…

  4. fantasai commented on Jun 9, 2021

    @fantasai
    Collaborator

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

  5. SimonSapin commented on Jul 19, 2021

    @SimonSapin
    ContributorAuthor

    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)

  6. added
    Commenter SatisfiedCommenter has indicated satisfaction with the resolution / edits.
    on Aug 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions