[csswg-drafts] [css-grid] Consider setting base sizes to growth limits when sizing under max-content constraint (#3646)

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

== [css-grid] Consider setting base sizes to growth limits when sizing under max-content constraint ==
Consider https://jsfiddle.net/ectdsqz5/

```css
.grid {
  display: inline-grid;
  grid-template-columns: max-content minmax(0, 100px);
  background: magenta;
}
.item {
  grid-column: 1 / 3;
  width: 100px;
  height: 100px;
  background: cyan;
}
```
```html
<div class="grid">
  <div class="item"></div>
</div>
```
The 2nd column has a growth limit of 100px. When the grid is sized under a max-content constraint, https://drafts.csswg.org/css-grid/#algo-grow-tracks will increase the column to these 100px.

However, when [distributing the width of the item across spanned tracks](https://drafts.csswg.org/css-grid/#extra-space)' base sizes, the formula only takes into account the base size, i.e. 0px:

> extra-space = max(0, size-contribution - ∑track-sizes)

So the 1st column ends up receiving the whole 100px contribution of the item, even if the 2nd column will end up being wide enough to contain these!

Instead of getting a 100px+100px=200px wide grid, wouldn't 0px+100px=100px make more sense? Once this size is known and layout is performed again for real, then the 2nd column won't be forced to increase, so using the base size as the spec currently says can make more sense, then the final result would be 100px+0px=100px.

More precisely, I'm proposing that each time the growth limit of a track is updated (and is finite), the base size is smaller, and the grid container is being sized under a max-content constraint, the base size should be increased to match the growth limit. This would be at the end of https://drafts.csswg.org/css-grid/#algo-init, https://drafts.csswg.org/css-grid/#algo-single-span-items, and https://drafts.csswg.org/css-grid/#algo-spanning-items (for each span amount).

Another advantage is that I think this will allow a nice optimization. Theoretically, if the grid container is sized shrink-to-fit, you may need to perform layout under a max-content constraint and under a min-content constraint, but this is double work. Instead, Chromium does it only once, and then estimates the min-content constraint size using the base sizes of the tracks, and the max-content constraint size using the growth limits. This seems to work well for non-spanning items, but fails for spanning ones (see https://crbug.com/930857, and Edge has the same problem). My proposal above should make base sizes effectively useless when under a max-content constraint, so it seems it would allow tweaking the optimization to behave properly in the spanning case while still avoiding two layouts (before the real one).

A downside is that, since the size distribution will behave differently once the size of the grid container is known, it can be possible that the tracks will end up being occupying more space than the container due to #2356. For example, by adding two `max-content` columns to the example above, and a grid item spanning columns 2-4 with a min/max-content contribution of 50px. When under a max-content constraint, the columns will sum 0px+100px+0px+0px=100px. But when laying out for real, the contribution of the 1st item will go to the 1st column, and the contribution of the 2nd item to columns 3-4, so the result will be 100px+0px+25px+25px=150px.

But of course, this kind of things can already happen now (just less likely), e.g. https://jsfiddle.net/jh3q5k1u/

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

Received on Tuesday, 12 February 2019 00:18:51 UTC