Skip to content

[css-grid-1] Distribution of intrinsic sizes according to flex factors doesn't handle sum < 1 #6078

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fantasai opened this issue Mar 4, 2021 · 9 comments
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-grid-1 Needs Testcase (WPT)

Comments

@fantasai
Copy link
Collaborator

fantasai commented Mar 4, 2021

https://www.w3.org/TR/css-grid-1/#algo-spanning-flex-items

if the sum of the flexible sizing functions of all flexible tracks spanned by the item is greater than zero, distributing space to such tracks according to the ratios of their flexible sizing functions rather than distributing space equally

Distribution of free space in “Expand Flexible Tracks” has special behavior for when the sum is less than one in order to get continuity between sum = 0fr and sum = 1fr, but this behavior is not reflected in the flex-dependent distribution rule under Resolve Intrinsic Track Sizes.

@Loirooriol
Copy link
Contributor

I already mentioned this possibility in #3694, but when we discussed it, not distributing the whole contribution didn't seem the right thing to do. Though I guess we could still distribute it all and have continuity by saying something like:

  1. If the sum of the flexible sizing functions is < 1, multiply the space to distribute by that sum.
    Otherwise use the space to distribute.
  2. Distribute that (if > 0) according to the ratios.
  3. Distribute the remaining space (if > 0) equally.

So, when distributing 100px among two flex tracks,

Tracks Current Continuous
0fr 0fr 50px 50px 50px 50px
0fr 0.1fr 0px 100px 45px 55px
0fr 1fr 0px 100px 0px 100px
0.1fr 0.3fr 25px 75px 40px 60px
0.2fr 0.6fr 25px 75px 30px 70px
0.3fr 0.9fr 25px 75px 25px 75px

@tabatkins
Copy link
Member

Yes, not distributing the space doesn't work here (since we're trying to size the tracks to the content, so they do need to grow). We currently distribute that space equally when the sum is 0, and proportionally when it is > 0. As shown by the first three rows in your table, your suggestion is a reasonable blend of the 0fr and 1fr behavior that creates continuity between the two states, so it sounds okay to us.

Agenda+ to confirm this change to the distribution rules is okay with the WG.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Grid 1 - sum of flex factures < 1, and agreed to the following:

  • RESOLVED: Accept proposal for continuous distribution of space to intrinsic grid tracks
The full IRC log of that discussion <fantasai> Topic: Grid 1 - sum of flex factures < 1
<fantasai> github: https://github.com//issues/6078
<fantasai> oriol: The specification says when taking into account the intrinsic contributions of items spanning flexible tracks, we distribute according to flex ratios of the tracks
<fantasai> oriol: We had a problem that all flexible tracks have 0fr, then have to divide by zero which is not well-defined.
<fantasai> oriol: So we resolved that in that case the distribution is done equally
<fantasai> oriol: Now we have the problem that this is not continuous
<fantasai> oriol: If you have 0fr to 0.00001fr, suddenly change from distributing equally to that track getting all the contribution
<fantasai> oriol: So proposal is to do the distribution continuously
<fantasai> oriol: If sum is >= 1 no change from now
<fantasai> oriol: if sum is zero, equal distribution as before
<fantasai> oriol: in between, we would [...]
<fantasai> oriol: we would multiply the space by the sum (which is < 1) and distribute that space proportionally
<fantasai> oriol: and distribute the rest of the space equally
<fantasai> oriol: This gives continuity between 0 and 1
<fantasai> Rossen: Any feedback?
<emeyer> fantasai: I think it’s a good change that makes sense and gives us continuity between 0 and 1.
<emeyer> dbaron: Does anything else in CSS act like this?
<emeyer> fantasai: Flex acts a little like this.
<dholbert> yeah, the flexbox spec says something similar for flex-grow < 1 -- we should be sure to make this as similar as possible.
<dholbert> for coherence
<fantasai> iank_: table percentage distribution acts a bit like this
<emeyer> fantasai: The main difference between this and flex is that here you distribute all the space but in flex you distribute some of it.
<fantasai> dbaron[m]: ok, seemed a little weird to only make the change in this place
<fantasai> iank_: Modulo web-compat...
<fantasai> iank_: I have a bug about 0frs and things
<fantasai> iank_: Depending on how widespread that is...
<fantasai> oriol: I don't think web-compat is problematic for this specific thing
<fantasai> oriol: Currently implementations are not taking into account intrinsic contributions of items spanning multiple flexible trakcs
<fantasai> oriol: gridNG implemented the right hting
<fantasai> oriol: if we had a compat problem, it would be more general problem
<fantasai> Rossen: not hearing any objections
<fantasai> RESOLVED: Accept proposal for continuous distribution of space to intrinsic grid tracks

@fantasai
Copy link
Collaborator Author

fantasai commented Jul 2, 2021

Edits checked in. @Loirooriol would you mind reviewing? (Close out the issue if it looks OK.)

@fantasai fantasai added Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. Needs Testcase (WPT) labels Jul 2, 2021
@Loirooriol
Copy link
Contributor

Maybe it would be clearer to handle this in https://drafts.csswg.org/css-grid/#extra-space rather than monkey-patching it in https://drafts.csswg.org/css-grid/#algo-spanning-flex-items, but I guess it's good.

@Loirooriol
Copy link
Contributor

Just some math, in case someone finds it useful.
When distributing among n tracks, the i-th one gets this fraction of the space:

  • If no flex tracks (equal distribution): 1 / n
  • If s ≥ 1: fⁱ / s
  • If 0 ≤ s < 1: fⁱ + (1-s)/n

where fⁱ is the flex fraction of thei-th track, and s = ∑fⁱ is the sum of flex fractions.

@dholbert
Copy link
Member

dholbert commented Nov 6, 2024

@Loirooriol or others: do we know if this spec-change was implemented anywhere? In particular, the part where we should distribute the remaining space equally after we've distributed a portion for the fractional-fr-units-that-sum-to-less-than-1. That is reflected in the spec at https://drafts.csswg.org/css-grid-2/#algo-spanning-flex-items ("...and the rest equally") but I'm not seeing any browser have that behavior.

I wrote a test with grid-template-columns: 0.1fr 0.3fr; and with a 100px-wide grid item that spans those two columns, and then I've got "marker" items in the next row to show how wide the columns end up being.
https://jsfiddle.net/dholbert/g1qowxrb/

With this spec change, I think the expected result of my testcase would be for the tracks to be 40px 60px, per the table that @Loirooriol provided in his comment above. But Chromium and WebKit currently end up with 25px 75px which seems to be the old behavior of just distributing proportionally. (Firefox does something else which is also clearly wrong.)

EDIT: here's the css/html from my jsfiddle above:

* { box-sizing: border-box; }
.grid {
  display: grid;
  grid-template-columns: 0.1fr 0.3fr;
  grid-template-rows: 80px 80px;
  border: 5px solid black;
   /* This size dosn't matter too much; it just has to
      a little bit bigger than our 100px-wide item. */
  width: 120px;
}
.item {
  width: 100px;
  grid-column: 1 / span 2;
  border: 3px solid blue;
}
.marker {
  border: 3px solid;
}
#elemA { color: orange; }
#elemB { color: fuchsia; }
<div class="grid">
  <div class="item">wide item</div>
  <div id="elemA" class="marker"></div>
  <div id="elemB" class="marker"></div>
</div>

@dholbert
Copy link
Member

dholbert commented Nov 6, 2024

Here's an example where I'm trying to get directly at the discontinuity around 0 that we were trying to fix here:
https://jsfiddle.net/dholbert/gypkm461/

This jsfiddle has 3 grids which have column sizes 0fr 0fr, 0fr 0.1fr, and 0.1fr 0.1fr. The expectation is that the second grid (the one with 0fr 0.1fr) should have its tracks sized ~similarly to the other two, with just a small difference in its column's sizes (one column should be 10px wider than the other, I think). But Chromium and WebKit collapse away that grid's first column entirely (as shown by the orange marker-item not showing up at all there).

(This is essentially testing the second row from @Loirooriol's table in in his comment above

So I think this is an indication that nobody has yet implemented this spec change; but please correct me if I'm wrong. Thanks! (This is on my radar because we've got an engineer working on getting Gecko up-to-date on this part of the spec right now.)

JSFiddle Source:

.grid {
  display: grid;
  grid-template-rows: 40px 40px;
  border: 5px solid black;
  margin: 5px;
  width: 120px;
}
.item {
  width: 100px;
  grid-column: 1 / span 2;
  border: 3px solid blue;
}
.marker {
  background: currentColor;
}
0 0:
<div class="grid" style="grid-template-columns: 0fr 0fr">
  <div class="item"></div>
  <div class="marker" style="color:orange"></div>
  <div class="marker" style="color:fuchsia"></div>
</div>
0 0.1:
<div class="grid" style="grid-template-columns: 0fr 0.1fr">
  <div class="item"></div>
  <div class="marker" style="color:orange"></div>
  <div class="marker" style="color:fuchsia"></div>
</div>
0.1 0.1:
<div class="grid" style="grid-template-columns: 0.1fr 0.1fr">
  <div class="item"></div>
  <div class="marker" style="color:orange"></div>
  <div class="marker" style="color:fuchsia"></div>
</div>

@Loirooriol
Copy link
Contributor

I kind of remember working on this for Blink's legacy engine, but possibly I didn't finish the patch, and LayoutNG rewrote the entire thing anyways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-grid-1 Needs Testcase (WPT)
Projects
None yet
Development

No branches or pull requests

5 participants