-
Notifications
You must be signed in to change notification settings - Fork 639
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-flexbox-1] Intrinsic Main Size algo has errors #7189
Comments
Proposed changes: diff --git a/css-flexbox-1/Overview.bs b/css-flexbox-1/Overview.bs
index 358740409..c5d628f65 100644
--- a/css-flexbox-1/Overview.bs
+++ b/css-flexbox-1/Overview.bs
@@ -2903,38 +2903,52 @@ Flex Container Intrinsic Main Sizes</h4>
For each <a>flex item</a>,
subtract its outer <a>flex base size</a> from its [[#intrinsic-item-contributions|max-content contribution]] size.
If that result is positive,
- divide by its <a>flex grow factor</a> floored at 1;
+ divide by its <a>flex grow factor</a>;
if negative,
- divide by its <a>scaled flex shrink factor</a>
- having floored the <a>flex shrink factor</a> at 1.
- This is the item's <var>max-content flex fraction</var>.
+ divide by its <a>scaled flex shrink factor</a>.
+ This is the item's <var>desired flex fraction</var>.
<li>
Place all <a>flex items</a> into lines of infinite length.
-
- <li>
Within each line,
- find the largest <var>max-content flex fraction</var>
+ find the greatest (most positive)
+ <var>desired flex fraction</var>
among all the <a>flex items</a>.
+ This is the line’s <var>chosen flex fraction</var>.
+
+ <li>
+ If the sum of the line’s <a>flex grow factors</a>
+ (<a>flex shrink factors</a>,
+ if the <var>chosen flex fraction</var> is negative)
+ is less than 1,
+ multiply the <var>chosen flex fraction</var> by that sum.
+
+ <li>
Add each item’s <a>flex base size</a>
to the product of its <a>flex grow factor</a>
- (or <a>scaled flex shrink factor</a>, if the chosen <var>max-content flex fraction</var> was negative)
- and the chosen <var>max-content flex fraction</var>,
+ (<a>scaled flex shrink factor</a>, if shrinking)
+ and the <var>chosen flex fraction</var>,
then clamp that result by the <a>max main size</a>
floored by the <a>min main size</a>.
<li>
- The <a>flex container</a>’s <a>max-content size</a> is the
- largest sum of the afore-calculated sizes of all items within a single line.
+ The <a>flex container</a>’s <a>max-content size</a> is
+ the largest sum (among all the lines)
+ of the afore-calculated sizes of all items within a single line.
</ol>
The <strong><a>min-content</a> <a>main size</a></strong> of a <em><a>single-line</a></em> flex container
is calculated identically to the <a>max-content</a> <a>main size</a>,
except that the <a>flex items</a>’ [[#intrinsic-item-contributions|min-content contributions]] are used
instead of their [[#intrinsic-item-contributions|max-content contributions]].
+
However, for a <em><a>multi-line</a></em> container,
- it is simply the largest [[#intrinsic-item-contributions|min-content contribution]]
+ the [=min-content=] [=main size=] is simply the largest [[#intrinsic-item-contributions|min-content contribution]]
of all the non-[=collapsed=] <a>flex items</a> in the <a>flex container</a>.
+ For this purpose,
+ each item's contribution
+ is capped by the item’s [=flex base size=] if the item is not growable,
+ and floored by the item’s [=flex base size=] if the item is not shrinkable.
<details class=note>
<summary>Implications of this algorithm when the sum of flex is less than 1</summary>
@@ -3003,17 +3017,13 @@ Flex Item Intrinsic Size Contributions</h4>
is the larger of its <em>outer</em> <a>min-content size</a>
and outer <a>preferred size</a> (its 'width'/'height' as appropriate)
if that is not ''width/auto'',
- clamped by its <a>flex base size</a> as a maximum (if it is not growable)
- and/or as a minimum (if it is not shrinkable),
- and then further clamped by its <a lt="min main size">min</a>/<a>max main size</a>.
+ clamped by its <a lt="min main size">min</a>/<a>max main size</a>.
The <strong>main-size <a>max-content contribution</a> of a <a>flex item</a></strong>
is the larger of its <em>outer</em> <a>max-content size</a>
and outer <a>preferred size</a> (its 'width'/'height' as appropriate)
if that is not ''width/auto'',
- clamped by its <a>flex base size</a> as a maximum (if it is not growable)
- and/or as a minimum (if it is not shrinkable),
- and then further clamped by its <a lt="min main size">min</a>/<a>max main size</a>.
+ clamped by its <a lt="min main size">min</a>/<a>max main size</a>. |
Explanation of proposed changes:
/cc @dholbert @davidsgrogan for review |
Thanks for working on this. Two things:
@@ -2903,38 +2903,52 @@ Flex Container Intrinsic Main Sizes</h4>
For each <a>flex item</a>,
subtract its outer <a>flex base size</a> from its [[#intrinsic-item-contributions|max-content contribution]] size.
If that result is positive,
- divide by its <a>flex grow factor</a> floored at 1;
+ divide by its <a>flex grow factor</a>;
if negative,
- divide by its <a>scaled flex shrink factor</a>
- having floored the <a>flex shrink factor</a> at 1.
- This is the item's <var>max-content flex fraction</var>.
+ divide by its <a>scaled flex shrink factor</a>.
+ This is the item's <var>desired flex fraction</var>. |
I think the new text gives this flexbox an infinite min and max intrinsic size. Is that intended? <div style="display: flex;">
<!-- contribution = 500 -->
<!-- fraction = inf -->
<div style="flex: 0 1 200px; width: 500px;"></div>
<!-- contribution = 200 -->
<!-- fraction = 50 -->
<!-- flex base size + largest fraction * flex grow factor = inf -->
<div style="flex: 2 0 100px; width: 200px;"></div>
</div> |
There's another technical issue around prescribing This happens when calculating min-content size in http://wpt.live/css/css-flexbox/intrinsic-size/row-001.html. Well, it's actually I think you intend for the result of that multiplication to be 0 here. |
Argh, all our test cases were looking at the shrinking case, where the "goes to infinity" behavior is fine because it's negative infinity and gets discarded, since the other value is more positive. We didn't even look at the growth case where the infinite behavior is the one that gets chosen. Looking into this... |
Okay, so there's no way to rescue continuity here with the existing behavior we've put in the spec. Given two flex items, each with a
The only way to rescue continuity is indeed to care about individual values <1; multiplying the (flex base size - contribution size) by the fraction first. (Or equivalently, floor the factor at 1 when calculating the desired flex fraction, which is what the original spec text did.) Since this would return us to the original spec text, I suspect that's why we wrote it that way originally; we must have been looking at growing cases rather than shrinking cases. So there are two options:
The issue, ultimately, is that the same goal - make at least one element reach its contribution size, and every other element be its contribution size or larger, given a single consistent fraction size - is produced asymmetrically for grow and shrink. In grow, you have to select the largest fraction to satisfy the goal, so the elements with a smaller desired fraction overshoot their contribution size; in shrink you have to select the smallest fraction, so the elements with a larger desired fraction stop before they get smaller than their contribution size. Both cases get an infinite blow-up for zeros and near-zeros, but that gets discarded in the shrink case but honored in the grow case. It might very well make sense to have these two cases require slightly different algos, then. |
I'm good with implementing this if you're good with speccing it. |
spec editors, I'd love it if you could work on this soon! (you're not waiting for me for anything, are you?) |
So @tabatkins and I worked out some edits for this issue. We tweaked the growth algorithm a bit to make the continuity curve less extreme (by the time we do layout, we've triple-applied the flex factor without the fix) by dividing the chosen flex fraction by the sum of the growth factors when that sum is < 1. Principles
Principle 6, which is a superset of 2, was what we sacrified in order to make the rest work. Sample Cases (based on your Apr 19 testcase but with varying flex-grow values)
@davidsgrogan @dholbert Let us know if it looks good, or if you notice any other concerns! |
Looks good. Implementing will be the real test, but I'm optimistic! Is d452a10 the only commit or are there more coming? |
That was it! |
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: [css-flexbox-1] Intrinsic Main Size algo has errors<fantasai> See https://github.com//issues/7189#issuecomment-1172771501 <dael> github: https://github.com//issues/7189 <dael> TabAtkins: This is a call for review from others. We found when reviewing WPT that the handling of intrinsic sizes of flexboex when sum < 1 wasn't correct. Have gone back and forth with dgrogan a few times. Pretty sure it's right now. <dael> TabAtkins: Found to avoid explosions to infinity need slightly different algo to get correct intrinsic size. David thinks they're fine. Anyone else, we would appriciate review. It's is subtle changes and if there are mistakes or violates other requirements would appreciate review <dael> fantasai: We should get resolution, but can have more time for review <dael> Rossen_: I was reading through commit linked in issue and it's quite involved. Would prefer to give time to reason through it <dael> Rossen_: I think even though some of it is notes they're complex and good to give time <dael> TabAtkins: Yeah. This was complicated enough I had to do 2 nested details. Definitely a little complex <dael> Rossen_: So in that case action to implementors of flexbox to please review the commit <Rossen_> commit to be reviewed https://github.com/w3c/csswg-drafts/commit/d452a10a921391dc6b6a96e7be97218692c1de53 <Rossen_> q? <dael> jensimmons: Do the WPT tests need updating or are they now accurate? <dael> TabAtkins: Not 100% sure but I believe tests will need updating. I think David will take care of that <dael> jensimmons: If he's not, recommend opening an issue on interop repo <dael> jensimmons: Just so they're aware <dael> jensimmons: I can file <dael> fantasai: I think intrinsic algo is a focus on there since it's been changing based on impl feedback <dael> Rossen_: Would be great to add the issue, thanks jensimmons |
There were a bunch of spec changes in w3c/csswg-drafts#7189 min-content sizes can be smaller than the previous revision called for. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3780146 Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1032174}
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3780146 Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1032174}
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3780146 Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1032174}
Okay, been six weeks since the last request for impl review. Agenda+ to close it. /cc @dholbert especially for eyes on this |
FYI, the new spec text is implemented in Blink behind a flag. |
…hm for single row containers, a=testonly Automatic update from web-platform-tests [css-flex] Update intrinsic size algorithm for single row containers There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3780146 Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1032174} -- wpt-commits: ade69d7bf5d4e7e6555f92b3501c7a986e21b3fa wpt-pr: 35214
The CSS Working Group just discussed
The full IRC log of that discussion<heycam> Topic: Intrinsic Main Size algo has errors<heycam> github: https://github.com//issues/7189 <heycam> TabAtkins: this one should be easier <heycam> ... we noticed an error, discovered what it was, talked it over with David, fixed it to his satisfaction <fantasai> https://github.com/w3c/csswg-drafts/commit/d452a10a921391dc6b6a96e7be97218692c1de53 <heycam> ... we asked for a review few weeks ago, if no comments, we can go ahead and accept it <heycam> fantasai: this is already folded into the spec <heycam> dholbert: I haven't had a chance to look <heycam> ... I could take a quick look offline. but I suspect it's fine. <heycam> Ian: we are still implementing this. don't know what the compat fallout will be <heycam> ... but we need to try to work out what that looks like <heycam> ... this is just a bit hairy because we've all had the same intrinsic sizing alg for a while <heycam> RESOLVED: Accept changes, close the issue |
@dholbert Mark Commenter Satisfied if you're happy with it, re-open if not! |
There were a bunch of spec changes in w3c/csswg-drafts#7189 The revisions make some min-content sizes smaller than the previous version. Bug: 240765 Change-Id: I3a879a34afb197a064e6bbf2d6407418561ea4a9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3780146 Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1032174} NOKEYCHECK=True GitOrigin-RevId: b4c0e7d90c9e0cf7161906c1b0a8c359c79a1cf6
There seems to be no changelog entry for this change here (https://drafts.csswg.org/css-flexbox/#changes-20181119). Is that intentional? (am I looking in the wrong place?) |
Reviewing testcases in web-platform-tests/wpt#33242, @fantasai and I found the handling of flex factors <1 is not quite right in the intrinsic main size algo.
Quoting from the issue:
Just as a note: the min-content contribution discontinuity error was added in 2c446be, from the conclusions in https://lists.w3.org/Archives/Public/www-style/2015Aug/0212.html. At the time, this wasn't an error, as the intrinsic sizing algo didn't have the flooring behavior for flex factors < 1.
The text was updated successfully, but these errors were encountered: