-
Notifications
You must be signed in to change notification settings - Fork 693
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
[css-grid] Unclear how to limit track growth by fit-content() argument #4549
Comments
My thoughts are:
So I propose something like: @@ -4161,8 +4161,6 @@ Resolve Intrinsic Track Sizes</h3>
a <a>max track sizing function</a> of ''max-content''
by <a href="#extra-space">distributing extra space</a> as needed
to account for these items' <a>max-content contributions</a>.
- However, limit the growth of any ''fit-content()'' tracks
- by their ''fit-content()'' argument.
</ol>
Repeat incrementally for items with greater spans until all items have been considered.
@@ -4233,13 +4231,15 @@ Distributing Extra Space Across Spanned Tracks</h4>
<pre><var>extra-space</var> = max(0, <var>size-contribution</var> - ∑<var>track-sizes</var>)</pre>
<li>
- <strong>Distribute space to base sizes up to growth limits:</strong>
+ <strong>Distribute space to base sizes up to limits:</strong>
Find the |item-incurred increase| for each spanned track with an affected size
by: distributing the space equally among such tracks,
freezing a track’s |item-incurred increase|
as its affected size + |item-incurred increase|
- reaches its <a>growth limit</a>
- (and continuing to grow the unfrozen tracks as needed).
+ reaches its <a>growth limit</a>.
+ Also freeze ''fit-content()'' tracks
+ when they reach their ''fit-content()'' argument.
+ In both cases, continue to grow the unfrozen tracks as needed.
If a track was marked as <a>infinitely growable</a> for this phase,
treat its <a>growth limit</a> as infinite for this calculation
@@ -4265,7 +4265,8 @@ Distributing Extra Space Across Spanned Tracks</h4>
if there are no such tracks, then all affected tracks.
<li>
when handling any intrinsic <a>growth limit</a>:
- all affected tracks.
+ any affected track that happens to also have an intrinsic <a>max track sizing function</a>;
+ if there are no such tracks, then stop distributing space.
</ul>
For this purpose, ''fit-content()'' tracks are treated as ''max-content'' |
…nce the actual handling for this case is already built into the called algo. #4549
After careful review, we actually think the spec is already complete and correct in this regard. The "Distribute extra space" algo already handles fit-content() explicitly, in exactly the way we want, in step 3. We very purposely do not want to apply fit-content() clamping to base sizes, because fit-content is supposed to respect its minimum size (here reflected as an "auto" min track sizing function) more strongly than either its specified or maximum size. All we want to do is treat the track like its max sizing function is "max-content" (thus affecting only the growth limit), unless that would make it larger than the specified length. However, the line at the end of the "max-content maximums" steps in steps 2 and 3 of Resolve Intrinsic Sizes is misleading - as your own confusion shows, it implies something additional needs to be done, when actually it's an editorial statement referring to the fit-content() handling already done in the Distribute Extra Space algo. We'll remove those. (That said, we've found several other minor mistakes or necessary clarifications in these sections while reviewing. :( ) |
Sure, fit-content is supposed to respect its minimum size. But IMO this should happen in step "3. Distribute space beyond growth limits" of the the Distribute Extra Space algo, not in "2. Distribute space to base sizes up to growth limits". Because |
Also "Size tracks to fit non-spanning items" doesn't use the Distribute Extra Space algo. So that removal seems wrong. |
Right, that sentence says "essentially" because it's editorial and not precise. |
Sure, we don't want to clamp to a max of 100px when distributing min contributions, because min wins over max. But we do want to clamp when distributing max contributions. Otherwise So, imagine
After your change, the Another case:
With the current spec, both tracks will end up with a base limit of 150px (since currently they have an infinite growth limit). What I'm saying is that the But of course, if there was no other track which could take these 200px, they definitely should end up going to the |
…eed need to stay around. Whoops. #4549
@Loirooriol OK, I see what you're saying. I think the spec is clear (fit-content() limits only affect the growth limits, not the base sizes), but agree that it's sub-optimal when distributing the minimum contribution of spanning items. It wasn't a case we considered very carefully. |
@fantasai OK, so now
|
Thinking better about this, in common cases the spanning algorithm doesn't clamp with fit-content limits at all. Which is bad. Consider this example#grid {
display: grid;
width: 200px;
grid-template-columns: fit-content(25px) 0px;
}
#item {
grid-column: span 2;
min-width: 0;
}
#item::before, #item::after {
content: '';
height: 50px;
width: 50px;
float: left;
} <div id="grid">
<div id="item"></div>
</div> The 2nd track just to trigger the spanning algorithm, has no effect. We run the spanning algorithm:
The 25px fit-content limit has been ignored, not just once but twice! So either revert 64494c0 completely and leave the exact clamping procedure undefined for now, or apply my suggestions. But with the current spec no clamping is actually enforced. |
@Loirooriol OK, Proposed fix: diff --git a/css-grid-1/Overview.bs b/css-grid-1/Overview.bs
index ff3b12ef8..5fffa1b73 100644
--- a/css-grid-1/Overview.bs
+++ b/css-grid-1/Overview.bs
@@ -4263,8 +4263,6 @@ Resolve Intrinsic Track Sizes</h3>
a <a>max track sizing function</a> of ''max-content''
by [[#extra-space|distributing extra space]] as needed
to account for these items' <a>max-content contributions</a>.
-However, limit the growth of any ''fit-content()'' tracks
-by their ''fit-content()'' argument.
</ol>
Repeat incrementally for items with greater spans until all items have been considered.
@@ -4341,7 +4339,9 @@ Distributing Extra Space Across Spanned Tracks</h4>
For [=base sizes=],
the |limit| is its [=growth limit=].
For [=growth limits=],
-the |limit| is infinity if it is marked as [=infinitely growable=],
+the |limit| is
+the ''fit-content()'' argument if has a ''fit-content()'' [=track sizing function=],
+infinity if it is marked as [=infinitely growable=],
and equal to the [=growth limit=] otherwise.
Note: If the affected size was a <a>growth limit</a>
@@ -4351,7 +4351,8 @@ Distributing Extra Space Across Spanned Tracks</h4>
<li>
<strong>Distribute space beyond limits:</strong>
If space remains after all tracks are frozen,
-unfreeze and continue to distribute space to the |item-incurred increase| of…
+unfreeze and continue to distribute space
+to the unfrozen |item-incurred increase| of…
<ul>
<li>
@@ -4372,7 +4373,7 @@ Distributing Extra Space Across Spanned Tracks</h4>
the [=max track sizing function=] of a ''fit-content()'' track
is treated as ''max-content''
until it reaches the limit specified as the ''fit-content()'' argument,
-after which it is treated as having a <a>fixed sizing function</a> of that argument.
+after which it is frozen at that [=fixed sizing function=].
Note: This step prioritizes the distribution of space Let us know if this seems correct? |
Good!
This doesn't seem entirely right. Because if a .grid {
display: grid;
grid-template-columns: fit-content(100px) minmax(auto, max-content);
}
/* minimum contribution = 0px
min-content contribution = 0px
max-content contribution = 0px */
.grid-item-1 { grid-column: 1 / 2 }
.grid-item-2 { grid-column: 2 / 3 }
/* minimum contribution = 0px
min-content contribution = 10px
max-content contribution = 100px */
.grid-item-3 {
grid-column: 1 / 3;
min-width: 0;
}
.grid-item::before {
content: "1234567890";
line-break: anywhere;
font: 10px/1 Ahem;
}
I would change it to:
Next:
No, we don't want to freeze permanently. Consider this case:
When the base sizes reach the fit-content limit, we want to stop considering them as having "an intrinsic max track sizing function". However, if we run out of tracks, we still want to distribute into them ("if there are no such tracks, then all affected tracks"). If we freeze, and only distribute to the unfrozen, we will skip them. Actually, we only want to freeze in this case:
So I would stick with my old proposal of @@ -4265,7 +4265,8 @@ Distributing Extra Space Across Spanned Tracks</h4>
if there are no such tracks, then all affected tracks.
<li>
when handling any intrinsic <a>growth limit</a>:
- all affected tracks.
+ any affected track that happens to also have an intrinsic <a>max track sizing function</a>;
+ if there are no such tracks, then stop distributing space.
</ul>
For this purpose, ''fit-content()'' tracks are treated as ''max-content'' or, if you want to freeze, let's split that step into 2:
|
BTW, while we are at it, this "it" is not much clear:
I guess it should be "the affected size + item-incurred increase". And afterwards there is another "it" which refers to something else, "the track" or "the max track sizing function", so it may be good to make that explicit too. |
Oh, and For [=base sizes=],
the |limit| is its [=growth limit=]. should probably be the smaller of the growth limit an the fit-content limit (if any). Because the growth limit is initially set to infinity for fit-content tracks. In other cases, the growth limit being greater than the fit-content limit should mean that the base size forced that, that is we already have Or alternatively, just initialize the growth limit of fit-content tracks to their argument (instead of infinity) in §12.4? This would also imply that fit-content tracks would never be marked as infinitely growable, avoiding the need to special-case them when finding the limit when distributing into growth limits. Edit: this would be simpler but may make fit-content tracks take more a bigger contribution than max-content tracks, breaking the principle that |
@Loirooriol Proposed edits: diff --git a/css-grid-1/Overview.bs b/css-grid-1/Overview.bs
index 4c8543864..bd499e5a8 100644
--- a/css-grid-1/Overview.bs
+++ b/css-grid-1/Overview.bs
@@ -4278,8 +4278,6 @@ Resolve Intrinsic Track Sizes</h3>
to the [=growth limits=] of tracks with
a <a>max track sizing function</a> of ''max-content'',
to accommodate these items' <a>max-content contributions</a>.
- However, limit the growth of any ''fit-content()'' tracks
- by their ''fit-content()'' argument.
</ol>
Repeat incrementally for items with greater spans until all items have been considered.
@@ -4370,10 +4368,15 @@ Distributing Extra Space Across Spanned Tracks</h4>
(and continuing to grow the unfrozen tracks as needed).
For [=base sizes=],
- the |limit| is its [=growth limit=].
+ the |limit| is its [=growth limit=],
+ capped by its ''fit-content()'' argument if any.
For [=growth limits=],
- the |limit| is infinity if it is marked as [=infinitely growable=],
- and equal to the [=growth limit=] otherwise.
+ the |limit| is the [=growth limit=]
+ if the [=growth limit=] is finite
+ and the track is not [=infinitely growable=],
+ otherwise its ''fit-content()'' argument
+ if it has a ''fit-content()'' [=track sizing function=],
+ and infinity otherwise.
Note: If the |affected size| was a <a>growth limit</a>
and the track is not marked [=infinitely growable=],
@@ -4400,14 +4403,16 @@ Distributing Extra Space Across Spanned Tracks</h4>
<li>
when accommodating any contribution
into [=growth limits=]:
- all |affected track|s.
+ any |affected track| that has an intrinsic [=max track sizing function=].
</ul>
For this purpose,
the [=max track sizing function=] of a ''fit-content()'' track
is treated as ''max-content''
- until it reaches the limit specified as the ''fit-content()'' argument,
- after which it is treated as having a <a>fixed sizing function</a> of that argument.
+ until the track reaches the limit specified as the ''fit-content()'' argument,
+ after which its [=max track sizing function=] is treated as being
+ a <a>fixed sizing function</a> of that argument
+ (which can change which tracks continue to receive space in this step).
Note: This step prioritizes the distribution of space
for accommodating |size contribution|s These changes aim to:
The overall principle is to match the smaller of If this looks good to you, we'll raise it to the WG for review! |
LGTM! |
…n accommodating spanning items. #4549
Agenda+ to approve #4549 (comment) |
The CSS Working Group just discussed
The full IRC log of that discussion<fremy> Topic: [css-grid] Unclear how to limit track growth by fit-content() argument<astearns> github: https://github.com//issues/4549 <fremy> fantasai: oriol opened an issue because the way we described fit-content for tracks that span multiple columns <fremy> fantasai: ... was not sufficiently specifieid <fremy> fantasai: ... the fit-content now cap the growh limit, and we also apply this when considering the base size, which we didn't do previously <fremy> fantasai: so we will now distribute up to the limit defined now <fremy> fantasai: oriol is happy about the edits we brought in <fremy> fantasai: but we need a resolution (and a review) <fremy> iank_: are there any test about these cases? <fremy> fantasai: not yet <fremy> fantasai: the test should be to add an item in a fit-content track next to an auto track <fremy> fantasai: and an item next to two fit-content tracks with various limits set on them <fremy> iank_: can we add tests to wpt? <fantasai> s/next to/spanned across/ <fremy> fantasai: yes, this is on my todo list <fremy> astearns: anybody want to do their own review before a resolution <fremy> proposed resolution is to accepted the edits <fremy> RESOLVED: accept the current edits for fit-content growth limits <fremy> fantasai: I verified that this is in my todo list <fremy> iank_: when you do the pull request on wpt, can you mention the issue? <fremy> iank_: this will help us link the tests in our system to make the changes <fremy> fantasai: TabAtkins and myself are clearing our way to the grid test issues <fantasai> s/test// <fremy> fantasai: it might be a while before we get to all of it |
From https://drafts.csswg.org/css-grid/#algo-spanning-items,
The last sentence could be applied in different ways, I can see 2 reasonable options:
Option A: In https://drafts.csswg.org/css-grid/#extra-space run step 2 as normal, but at step 3 'Update the tracks' affected sizes' clamp the planned increase, i.e.
becomes
Option B: impose this limit during step 2.
The 'Distribute space to base sizes up to growth limit' is not affected, it's no-op since the affected size is a growth limit in this case.
During 'Distribute space beyond growth limits', when it says
actually only distribute among the tracks that are still treated as having a max-content max track sizing function, and stop distributing once they reach their fit-content() argument and start being treated as fixed.
With both options we may end up not distributing all the space (all tracks could have
fit-content(0)
). The difference is that with option A we are more likely to distribute less space, while in B we will fallback to distributing to other tracks if possible.Actually I don't really understand what the spec is trying to do by limiting the growth by the fit-content() argument only when dealing with max-content maximums, but not for intrinsic maximums. I also wonder whether 'Distribute space to base sizes up to growth limit' should freeze when a base size reaches a fit-content() argument smaller than the growth limit, and leave further increases for 'Distribute space beyond growth limits'.
The text was updated successfully, but these errors were encountered: