[csswg-drafts] [css-grid] Intrinsic contributions for items spanning flex tracks are not web compatible (#4783)

Loirooriol has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-grid] Intrinsic contributions for items spanning flex tracks are not web compatible ==
The behavior used to be:
 - If an item with span 1 is in an intrinsic flex track, its intrinsic contribution is taken into account.
   This is done in [§11.5.2](https://drafts.csswg.org/css-grid/#algo-single-span-items) simultaneously with contributions of items with span 1 in intrinsic non-flex tracks.
 - If an item with span>1 includes a flex track, its intrinsic contribution is ignored.

The spec was later changed (#2177 and follow-ups) to make it more consistent:
 - Intrinsic contributions of items spanning some intrinsic track are always taken into account.
 - For items with span>=1 that include some intrinsic flex track, this is done grouping all such items together (not by span). And it happens in [§11.5.4](https://drafts.csswg.org/css-grid/#algo-spanning-flex-items), after distributing contributions of items with span>1 that don't include any intrinsic flex track.

I tried to implement this in Chromium ([bug 935102](https://crbug.com/935102)), but it doesn't seem web compatible ([bug 1051039](https://crbug.com/1051039)), so I had to revert. There are basically 2 problems.

## Problem 1

It seems that it's kinda popular to divide the grid into 12 equal columns, and then add a class to the items specifying how many columns should be spanned.

.grid { display: grid; grid-template-columns: repeat(12, 1fr) }
.col-8 { grid-column: span 8; background: green }
.col-4 { grid-column: span 4; background: red }
.single-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
<div class="grid">
  <div class="col-8">
    <div class="single-line">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed erat in ante posuere ornare vel vel mi. Curabitur et mi ac ex suscipit ultrices. Fusce non enim rhoncus, rhoncus sapien ut, ullamcorper mauris. Etiam nec lectus id nulla sagittis vehicula sed vitae orci. Praesent iaculis sodales ipsum. Nam placerat, quam ut facilisis fermentum, augue nibh condimentum nunc, in mattis turpis magna at risus. In ante nunc, sagittis ac vestibulum dapibus, laoreet in lectus.</div>
  <div class="col-4">Foo</div>

Used to look like


But gotcha, [`1fr`](https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-flex) means means `minmax(auto, 1fr)`, so the columns are intrinsic! If the contents of some column are big, they will make the column big too.


Note that the spec change was totally reasonable, it just made the testcase behave like

.grid { display: grid; grid-template-columns: 8fr 4fr }
.col-8, .col-4 { grid-column: span 1 }

Authors should be using `minmax(0, 1fr)` instead, or `min-width: 0`. But they are using `1fr` because it's simpler and used to work as they wanted.

## Problem 2

This affects authors who are aware that `1fr` is intrinsic and may "explode" the grid. They didn't want this, so they sized the flex columns with `minmax(0, 1fr)`. However, they also have non-flex columns, and items spanning both kinds of columns:

.grid { display: grid; grid-template-columns: auto minmax(0, 1fr) }
.item1 { background: cyan }
.item2 { background: green }
.item3 { grid-column: span 2; background-color: red }
<div class="grid">
  <div class="item1">Foo</div>
  <div class="item2">Bar</div>
  <div class="item3">Lorem ipsum dolor sit amet, consectetur adipiscing elit.

The `auto` column used to be sized tight for item1, and the flex column took the remaining space:


However, with the change, the intrinsic contribution of item3 is no longer ignored. And since the flex column is not intrinsic, the whole contribution is distributed into the 1st column:


So using `minmax(0, 1fr)` seems a mistake, authors should have used `1fr` so that the column remains intrinsic, but then use `min-width: 0` to set the [minimum contribution](https://drafts.csswg.org/css-grid/#minimum-contribution) of item2 and item3 to 0.

According to [bug 1051039#c21](https://bugs.chromium.org/p/chromium/issues/detail?id=1051039#c21), `minmax(0, 1fr)` got popular from https://css-tricks.com/preventing-a-grid-blowout/, https://stackoverflow.com/q/52861086, "numerous other questions and their answers on Stackoverflow", and "even Rachel Andrews recommends to use `minmax(0, Nfr)`".

## Possible solution

It would be a pity to go back to ignoring intrinsic contributions of items spanning multiple tracks with at least 1 flexible. But there could be a less drastic solution, hopefully still web compatible.

I think we could say that the [automatic minimum size](https://drafts.csswg.org/css-grid/#min-size-auto) should be 0 if the item spans multiple tracks with at least 1 flexible. Assuming that `width`/`height` behaves as `auto`, then this will set the [minimum contribution](https://drafts.csswg.org/css-grid/#minimum-contribution) to 0. So, the intrinsic contributions will be ignored by default as they used to, but they will be respected

 - If you size the grid item explicitly, e.g. set `width: 100px` or `min-width: 100px`
 - If you size the column with a non-`auto` intrinsic minimum, e.g. `minmax(min-content, 1fr)`.
 - When sizing the grid under a min-content or max-content constraint (since then an `auto` min track sizing function uses the [limited min-/max-content contribution](https://drafts.csswg.org/css-grid/#limited-contribution) instead of the [minimum contribution](https://drafts.csswg.org/css-grid/#minimum-contribution)).

Cc @fantasai, @tabatkins, @MatsPalmgren, @rachelandrew, @mrego 

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4783 using your GitHub account

Received on Monday, 17 February 2020 15:07:13 UTC