[csswg-drafts] [css-grid] Intrinsic size of grid containers

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

== [css-grid] Intrinsic size of grid containers ==
The [spec text](https://drafts.csswg.org/css-grid/#intrinsic-sizes)
is very clear about this and has been around for a long time:
> The max-content size (min-content size) of a grid container
> is the sum of the grid container's track sizes (including gutters)
> in the appropriate axis, when the grid is sized
> under a max-content constraint (min-content constraint).

But it seems not all the browsers are doing it, or at least not all
are doing it properly.

Firefox is following the spec, and it runs the track sizing algorithm twice
(one under min-content constraint and another under max-content constraint)
to compute the min|max-content widths of the grid container.

However Blink and WebKit follow a different approach.
In this case they just run the track sizing algorithm once
with an available space of zero and use the sum of base sizes
as min-content size and the sum of the growth limits as max-content size.
The reason why these browsers do it that way is because
[this was suggested back in 2013 by Julien Chaffraix in `www-style`](https://lists.w3.org/Archives/Public/www-style/2013Oct/0581.html)
and never modified later.

Regarding Edge I don't know what's their implementation, but I'm finding
the same issues than in Blink and WebKit. So I guess Edge is either
not following the spec or not implementing it properly.

Let's go to the examples and why I'm bringing up this issue.

The key part of the track sizing algorithm that is affected by this
is when we [resolve intrinsic track sizes](https://drafts.csswg.org/css-grid/#algo-single-span-items)
(for both non-spanning and spanning items we have a similar text):
> * For auto minimums:
>   If the track has an auto min track sizing function and the grid container
>   is being sized under a min/max-content constraint,
>   set the track's base size to the maximum
>   of its items' min/max-content contributions, respectively.
>   Otherwise, set its base size to the maximum
>   of its items' min-size contributions.

Imagine the following example:
<div style="width: 20px; border: thick dotted red;">
  <div style="display: inline-grid; border: solid thick;">
    <div style="min-width: 0px; background: lime;">Lorem ipsum.</div>

The intrinsic sizes should be:
* min-content size: The width of *Lorem*, let's say `50px`.
* max-content size: The width of *Lorem ipsum.*, let's say `100px`.

As the grid container is `inline-grid`, its sized as [`fit-content`](https://drafts.csswg.org/css-sizing-3/#fit-content-inline-size):
`min(max-content size, max(min-content size, stretch-fit size))`.
In this example, `min(100px, max(50px, 20px)) = 50px`.

*Note: This also matches what happens in a similar case using `inline-block`
instead of `inline-grid`.*

![Output in Firefox vs other browsers of the previous example](https://user-images.githubusercontent.com/11602/36103589-0c5070ec-1010-11e8-8e2a-585ffac725a1.png)

In Blink and WebKit we always go through the *Otherwise* paragraph,
so the min-content size is `0px` and the final width is `20px`.
The same result happens on Edge, though I don't know how is that implemented.
In any case it seems quite clear that this is a bug in Blink, WebKit and Edge
and their behavior should be modified.

Note that to fix this, we'll need to follow a similar approach than Firefox,
which means that the track sizing algorithm will be run 3 times:
* 2 times to calculate the min and max-content sizes
  (one under min-content constraint and another under max-content constraint).
* And one extra time during layout considering no constraints.

This is not all, now let's go to a different example:
<div style="display: inline-grid; grid-template-columns: minmax(auto, 0px); border: solid thick;">
  <div style="background: lime;">Lorem ipsum.</div>

To calculate the min-content size, all the browsers seem to apply the clamping
described in [*Automatic Minimum Size of Grid Items* section](https://drafts.csswg.org/css-grid/#min-size-auto)
of the spec. So the min-content size is `0px`.
However to calculate the max-content size, Firefox uses
the max-content contribution as requested by the spec, that's `100px`.
This makes that the intrinsic size of the grid container is `100px`.
However during layout the track sizing algorithm is run again,
and as during layout it doesn't know if it's under a min-content
or max-content constraint, it goes through the *Otherwise* sentence
and apply the clamping, so the track has `0px` width.
This causes a weird effect as the track is `0px`
but the grid container is `100px`.

![Output in Firefox vs other browsers of the previous example](https://user-images.githubusercontent.com/11602/36103750-8a47a920-1010-11e8-9bb7-14caeddafac6.png)

In Blink and WebKit the result is better, the grid container is `0px`
as we always go through the *Otherwise* sentence and apply the clamping.
Edge has the same output too.

In a [Firefox bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1427608#c10)
@MatsPalmgren suggests that we apply the automatic minimum size clamping
when we are under a min-content constraint, max-content constraint
or no constraint.
That would make Firefox has the same output than the other browsers
in this last example.

It'd be nice to get the feedback from @atanassov about this issue,
as we don't know how the intrinsic size is being calculated in Edge.

Check the following codepen to see the examples live and play with them:

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

Received on Monday, 12 February 2018 15:21:18 UTC