-
Notifications
You must be signed in to change notification settings - Fork 715
[css-flexbox][css-grid] Intrinsic sizing with ∑flex < 1 is broken #1735
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
Comments
I think the correct fix to Flexbox is to add
|
Here's a well-formatted testcase showing off the behavior in Flexbox and Grid: https://jsfiddle.net/Lbvz57zj/4/ Chrome's behavior:
Firefox's behavior:
Ideal behavior for both Grid and Flexbox:
|
Actually, that fix is only correct if the flex basis is zero. We need to do something a little more complicated here. |
OK, new fix:
(Yes, “rescaled scaled” sounds a bit silly.) |
Okay, so example problem showing off non-zero base sizes: Two flex items, both have a max-content size of 200px, both have Ideal outcome: First item wants to grow, second wants to shrink, so per standard flex rules, we're growing. It wants to get 40% of the way toward its ideal (max-content) width, so should land at 140px. Second item wants to grow the same amount, so it should land at 340px. ("Idealness" is defined as "gives reasonable continuous behavior as the flex values change from 0 to >=1" and vice-versa. A max-content flexbox with all inflexible items should definitely just sum the flex basises of its items, and not pay attention to their max-content size at all.) Algo walkthrough:
Then we actually run flex layout inside that flex container. Container is 500px wide, sum of base sizes is 400px, free space is 100px. Items thus grow. Both have a flex-grow factor of .4, so they each get 40px of space added to their base size, resulting in 140px and 340px. Success! |
Just ran the above example for differing flex-grow factors as well; specifically, factors of .4 and .5. End result is that step 4 yields a size of |
Wording proposal for Grid:
|
(And I've run this Grid text thru the same examples - as far as I can tell, Chrome's current behavior is exactly correct per spec, and this edit will make the sum<1 case match our ideal behavior.) |
The Working Group just discussed
The full IRC log of that discussion<dael> Topic: Intrinsic sizing with ∑flex < 1 is broken<dael> Github: https://github.com//issues/1735 <dael> fantasai: There was an error in the algo for flexing for intrinisic size. We look at flexing algo in compo with min/max sizes so we give continer enough space so when flexing algo takes place min/max are respected. The error was when flex values add up to less than one. <dael> fantasai: TabAtkins and I proposed fixes, we think are correct. We're happy to edit them in. If anyone wants to review, great. We're pretty confident. <dael> dbaron: Are impl signed up to make thesE? WEll, does change match existing impl? <dael> fantasai: Current impl don't account for the flexing in calc of intrinisc. For grid we have impl that do that. THis change is fixing a behavior that doesn't seem right. I think chrome is the one that does that...I don't remember other impl. <bkardell_> present +bkardell_ <dael> dbaron: My worry is if somebody tries to impl do websites depend on old <dael> fantasai: There's 2 steps of impl. 1 is if you have the algo tweak it. That would be to grid where I don't think we have any dependency. I think for sure we should fix that. For flexbox the algo overall isn't impl so changing the algo won't affect impl. <dael> fantasai: dholbert has volunteered to impl the algo, but he hasn't gotten to it. <dael> TabAtkins: They impl a simplier version of the algo and they are consistant in that, but it's wrong and dholbert is offering to fix that. <dael> fantasai: And that will make it more consistant with grid <dael> dbaron: And if dholbert succeeds will other impl follow? <dael> TabAtkins: Yes, we will <dael> astearns: Has dholbert reviewed this proposed change? <dael> TabAtkins: We pinged him, he hasn't yet been able to do a full review. <dael> fantasai: It's not difficult to do, it's a tweek to some math. Largely it's a q of did we get the math right. <TabAtkins> (Re: compat, we implement an *almost* correct version of this for Grid already, the tweak to fix it only changes grids with a sum of fr < 1.) <dael> astearns: I'd be okay with getting it edited in, but I'm a little concerned no one has checked the math. I'd be happier if someone looked and said yay or nay <dael> fantasai: We can resolve and say it takes effect once verified. <dael> astearns: BUt that doesn't get us closer to pub <dael> fantasai: It does b/c if we replies today or tomorrow we can get it into pipeline <TabAtkins> (Our Flexbox impl is currently the "simple and dumb" version, which matches what Firefox currently does for both Grid and Flexbox; if dholbert fixes in Gecko and it sticks, we're happy to change ours to match.) <dael> astearns: Does it make sense to publish even if this doesn't make it? <dael> fantasai: Yeah, there's a ton of changes. THis is a CR so changes pub takes 6 weeks. Might as well start. <dael> Chris: If it takes 6 weeks is dependant on how good DoC and changes are and availability. <dael> fantasai: DoC is compiled. <fantasai> s/availability/availability of Ralph and plh/ <dael> astearns: Any other comments on resolving or resolve pending dholbert? <dael> fantasai: I'd prefer to get resolutions in place b/c that will get things rolling <dael> Chris: I agree. <dael> astearns: You propose to resolve we take this edit as soon as dholbert gives a thumbs up. Obj? <dael> RESOLVED: take this edit as soon as dholbert gives approval |
…ex containers when tracks/items flex factors sum to less than one. #1735
Edits from #1735 (comment) and #1735 (comment) checked in as 5c66e72 and added to DoC. Waiting now for @dholbert’s review. :) (Side conversation with @astearns about step 1 wording fixed over in #1803) |
My first nit: This section starts out:
That doesn't seem to be accurate anymore. (And maybe it was never strictly accurate even with the old spec text, in cases of inflexible items with flex-basis values smaller than their max-content contribution) In @tabatkins' example above (#1735 (comment) ), we end up at a max-content size of 500px, but really "the smallest size the flex container can take while maintaining the max-content contributions of its flex items" would be considerably larger than 500px. It'd be whatever size the container would need to be so that the first item end up at 200px. I think the issue is that "maintaining the max-content contributions of its flex items" is not strictly the goal here. Rather, it's something more like "maintaining the max-content contributions of its flex items, as much as their flex factors will allow, in light of our desire for continuity with 0". So that first sentence probably needs to get either more specific or more vague, so that it's not stating something that's strictly false? |
Yes, that's a more accurate statement. Now to get it shortened to something pithy. ^_^ |
My second nit: the math/units don't work out when we're using scaled flex shrink factor. Example below to illustrate this. Scenario: Just one flex item (for simplicity) with max-content size of Ideal outcome (I think?): flex container should end up exactly 200px wide (forcing item to shrink to its max-content size). Walkthrough of what the current draft's algorithm would do:
I think some piece of this algorithm wants to use the |
My third nit (on wording that might get changed in addressing second nit): the algorithm uses the term "rescaled scaled flex shrink factor*" without clearly explaining what that is. These parts are clear IMO:
... but "rescaled scaled flex shrink factor" is never defined. I assume it probably would be "rescaled flex shrink factor" times the flex base size (i.e. the scaled flex shrink factor, calculated using the rescaled flex shrink factor instead of the real one)? But this isn't super clear. |
Proposed changes to address @dholbert‘s last two comments:
This change switches us back to using flex shrink factors in place of scaled shrink factors, and introduces the concept of flex base ratio as a multiplier instead. |
OK, so I checked that in. @dholbert @tabatkins Could you review so we can tell @svgeesus to republish asap? :) |
One more issue I'm noticing: suppose we consider Tab's example above #1735 (comment) and we make one tweak -- we add Possible solution: in step 4...
...maybe that mention of "flex base size" should really be "outer flex base size"? |
Possible problem (not sure): the current algorithm is discontinuous when a flex factor reaches 0. Consider a simple scenario with just a single flex item, with
This distinction makes some sense to me -- if the flex item isn't flexible, then clearly it's not going to be able to grow at all beyond its And on the other hand, for all nonzero flexibilities, it seem reasonable to always size the container to the (sole) item's full max-content size (as the "target size") and then let the flex layout algorithm size the item to some intermediate growth point towards that target, depending on whether the flexibility is fractional or not. (This is basically what would happen with the algorithm as-written now.) Still: despite this apparent reasonableness, it's unfortunate that this creates a discontinuity. Maybe we should try to set up the algorithm so that its behavior for inflexible items is equal to the limit of its behavior for flexible items with fractional flexibilities? (I think that was part of the motivation here, right?) Or would that cause other problems? [1] Just in case it's not clear why the algorithm produces 100px in the "flex-grow is exactly zero" case: the easiest way to see this is to just jump straight to step 5, which computes |
Indeed, having a discontinuity is not ideal. :(
The problem here is that it would be really confusing if inflexible items create space in the container that they don't consume. I guess our options are to revert the fix here, or to accept the discontinuity in flex container sizing? Or is there another option? |
Okay, the discontinuity is definitely bad; I can't accept an algorithm that has it. This sucks. :( So yeah, if we avoid a discontinuity, there's only two options:
I think the drawback of #2 is probably much worse than the drawback of #1; slightly non-intuitive sizing in a minority case vs breaking a pretty universal and useful layout guarantee has a pretty clear winner, I think. So, we should revert, and then double-check that the original text does indeed do what we (now) want, and has no other unintended consequences. |
…d opening paragraph wording, and add some notes about the behavior so we remember our intentions in the future.
I've reverted to the previous text; on review, it does seem to do what we now want to do. Confirmation of that would be appreciated! I carried over the modification to the opening paragraph, and added an explanatory note to the end of the section. |
…apply the adjusted opening paragraph wording, and add some notes about the behavior so we remember our intentions in the future. w3c/csswg-drafts@efc9c7d
The Working Group just discussed
The full IRC log of that discussion<TabAtkins> Topic: Flex sum < 1<TabAtkins> GitHub: https://github.com//issues/1735#issuecomment-332671797 <TabAtkins> astearns: My understanding was that we had a resolution, but we had to revert it because there was a discontinutiy. <TabAtkins> fantasai: Yes, we need to be continuous for a given flex item going from 0=>1, *and* for the flex container when its children do the same. <TabAtkins> fantasai: Previous resolution fixed the flex item, but it created a discontinuity for the flex container. <TabAtkins> fantasai: So our proposal ends up giving non-linear behavior for flex items when the sum is <1, but it's continuous. <TabAtkins> astearns: Has dholbert looked at the revert? <TabAtkins> TabAtkins: He hasn't commented yet, so if he's seen it he hasn't approved it. <TabAtkins> astearns: So should we wait until we get feedback? <TabAtkins> TabAtkins: I'd prefer to get someone invested to give positive feedback. <TabAtkins> rego: I think we should accept the proposal. <TabAtkins> astearns: Have you reviewed the reverted text. <TabAtkins> rego: No, haven't checked the new text specifically, but I want continuity. <TabAtkins> astearns: fantasai, what do you want to do? <TabAtkins> fantasai: Resolve to revert to the previous text unless dholbert has opposite ideas. <TabAtkins> astearns: Any objections to reverting? <TabAtkins> RESOLVED: Revert the previous resolution regarding flex sum <1 (as has already been done) and solicit dholbert's review. |
I'll run through the current (reverted) text with some scenarios tomorrow, and I'll post any issues that I find. |
The current text on https://drafts.csswg.org/css-flexbox-1/#intrinsic-main-sizes looks good to me! A few nits on the "Implications of this algorithm when the sum of flex is less than 1" informational section that comes right after the algorithm:
|
The relevant text for Grid was reverted and the result of the final text looks good to me. |
All right, nits fixed. Thanks, y'all! |
The Intrinsic Main Sizes algorithm in Flexbox fails to handle cases where the sum of the flex factors is less than one. It creates a container that fits too snugly, so when the flex algorithm is run to set the sizes of the items, they are too small: essentially the multipliers are multiplied twice.
We should fix this, and for Grid, too.
The text was updated successfully, but these errors were encountered: