Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
[css-grid] Resolving 'fr' flexible lengths during intrinsic sizing of grid items #1120
In section 7.2.3 of Grid we specify that resolving 'fr' units with summed value of less than 1, during intrinsic sizing, should match Flexbox. Looking at the current implementations in Chrome and Firefox the behavior doesn't seem to match that expectation.
Consider this test case. The expectation is that when the sum of all fractions is less than one we have the special case. The implementations behavior is inconsistent and it appears to be triggered when at least one 'fr' value is less than 1.
If these are implementation bugs I can follow up with filing them but I'd like to make sure the spec is clear and if not we should be more explicit.
Here's a reference of the correct behavior in flexbox here.
If I understood the issue correctly, the problem is not that the sum is less than 1, but that for indefinite sizes, we may have to use 1 for fractional flexible lengths.
This issue was addressed long time ago, see the following thread for details:
Interesting! Javi's right that "sum less than 1" isn't quite the issue. The different between Grid and Flexbox here is in how we calculate the size of the container when some of the items have <1 flexibility, and the available space is indefinite (such as in a float).
Specifically, Grid's behavior is defined in https://drafts.csswg.org/css-grid/#algo-flex-tracks, the "If the free space is an indefinite length" substep. In your examples, it ends up computing a "used flex fraction" of 100px. In the .5/1 example, then, the tracks get sized to 50px/100px, respectively, and the grid then shrinkwraps those two tracks, being 150px wide total.
In Flexbox, the behavior is defined in https://drafts.csswg.org/css-flexbox/#intrinsic-sizes, where the "max content flex fraction"s end up computing to 0, and each item has a flex base size of 100px (due to its contents), so the flex container's size is the sum of (FBS + MCFF) for each item, or 200px wide total. If there's a .5/1 flex on the children, the sum of flexes is >1, so they then distribute that 200px with a 1:2 ratio, making the items approximately 67px/133px wide. (If the sum is <1, they get sized to an appropriate fraction of the 200px, leaving some empty space in the flexbox. The container does maintain its 200px width regardless, tho.)
I'm pretty sure Flexbox is the one with the bad behavior here. The container should pay attention to <1 flex values when finding its size, like Grid does. I'll file a bug for Flexbox instead.
referenced this issue
Mar 30, 2017
The Grid spec is still somewhat misleading. Consider the part of the spec:
In this part, the spec we refer to "free space" and show
free space is defined as: (https://drafts.csswg.org/css-grid/#free-space)
This implies that for example like : (https://jsfiddle.net/73oq0wqc/)
Here, both tracks have base size of 50px, the the free space is 150 - 50 - 50 = 50. And two tracks divide this 50px 1 to 2. But that is not what is happening. Instead, the final track size is 50px and 100px in all browsers.
Finding the size for fr (https://drafts.csswg.org/css-grid/#algo-find-fr-size), "Let leftover space be the space to fill minus the base sizes of the non-flexible grid tracks. " note that this time only minus base size of non-flexible tracks. In our example, both are flexible tracks, so “leftover space” is the entire 150px.
A similar issue arises when the sum of fr-unit is less than one.
In https://drafts.csswg.org/css-grid/#fr-unit , there is a note: "Note: If the sum of the flex factors is less than 1, they’ll take up only a corresponding fraction of the free space, rather than expanding to fill the entire thing. This is similar to how Flexbox [CSS-FLEXBOX-1] acts when the sum of the flex values is less than 1. "
This implies that the following example: (https://jsfiddle.net/kb0exLay/)
Free space is 200 - 50 -50 = 100. And the base on the note above, 100*0.9 is consumed by two fr tracks, remaining only 10px.
Note that https://drafts.csswg.org/css-grid/#algo-find-fr-size is quite different from what Edge does but we could update our implementation for interop.
One more part that is not entirely clear is determining the size of container.
For width: https://jsfiddle.net/Lbvz57zj/
Firefox appears to be determining the size of the box based on https://drafts.csswg.org/css-grid/#intrinsic-sizes. And then in second pass, use the determined width as definite
But in Chrome, they appear to be doing https://drafts.csswg.org/css-grid/#algo-find-fr-size directly with indefinite width. After one pass, they are doing it again with width from first pass.
They might be doing this due to https://drafts.csswg.org/css-grid/#algo-terms saying:
Firefox and Chrome both appears to be doing one pass of https://drafts.csswg.org/css-grid/#algo-find-fr-size with indefinite space.
added a commit
Aug 17, 2017
added a commit
Aug 17, 2017
Indeed; this appears to be a terminology mixup. Locally in that section, "free space" is correctly defined as subtracting out only the non-flexible tracks, but the "free space" term in the grid algorithm, as you point out, has a different meaning of subtracting out all the base sizes. We've changed the term from "free space" to "leftover space" to be more consistent with the terminology in the Track Sizing Algorithm section.
It would be interesting to know what, exactly, those differences are.
As far as I can tell, Chrome's Grid behavior is correct per spec right now, but implementations haven't yet caught up with the corresponding section in Flexbox. (We recently made some edits to this, and ended up reverting them; #1735 has the details.)
Let us know if there's anything left to do on this issue. (And again, we'd be interested to know about Edge's behavior for
In order to avoid blowing up the intrinsic content size when a single flexible track approaches 0 (even if the sum is > 1), the grid spec treats flex factors < 1 as 1 during https://drafts.csswg.org/css-grid/#algo-find-fr-size (otherwise if you had 0.01fr and 1fr tracks with similar max-content values, the second track would blow up in size). This is a slightly different approach than the one flexbox took when the space is indefinite, but when the space is definite I think they are equivalent. Edge and Firefox current implementations are closer to the flexbox algorithm, but we (Edge) can change if this is the behavior we want to stick with.
At first I thought Chrome's algorithm wasn't per-spec, but after reading through the algorithm carefully, I think Chrome's behavior does indeed match the spec. See https://codepen.io/anon/pen/JOqOey for an explanation.
The Working Group just discussed
The full IRC log of that discussion<dael> Topic: Resolving 'fr' flexible lengths during intrinsic sizing of grid items
<astearns> github: https://github.com//issues/1120
<dael> astearns: I'm not up on this issue. What was your comment Rossen_ ?
<dael> Rossen_: We are most likely going to have to change. We're okay with it, it will be simple. I'd like TabAtkins and fantasai to give this a read one more time. If they're still okay with current resolution we don't have to re-open. If they find additional points we can bring it back. for now I don't see a reason to re-open
<dael> fantasai: Our analysis from the comment is there was a clarifaction place and a language point. We checked in those. We couldn't find any other wanted change then those errors. We checked that in and asked Rossen_ if there's anything else. I'm guessing he said no.
<fantasai> s/language point/error in terminology/
<dael> Rossen_: Mostly. We can discuss if after you read the comment you feel like we need to discuss.
<fantasai> s/those/those fixes/
<dael> astearns: Sounds like action is for fantasai to take a look and if everything is fine she can mark as commentor satisfied.
<dael> Rossen_: Yes.
<dael> astearns: Good fantasai ?
<dael> fantasai: Yeah.