-
Notifications
You must be signed in to change notification settings - Fork 3k
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
flex container's intrinsic width and stretched images #28805
Comments
My initial reaction is that this seems reasonable, if it's web compatible. Thinking a bit more... I wonder if there'll be some weird interplay, in cases where the Consider e.g. this example, where I've basically stuck your jsfiddle inside of a column-oriented flex container: .colflex {
display: flex;
flex-direction: column;
height: 200px;
width: max-content;
border: 2px solid fuchsia;
}
.text {
border: 2px solid gray;
}
.rowflex {
display: flex;
height: 50px;
flex: 1 0 50px;
border: 2px solid teal;
width: max-content;
}
* {
/* Turn off automatic minimum sizes, to reduce the amount of potential
magic behavior that's in play: */
min-width: 0;
min-height: 0;
} <div class="colflex">
<div class="text">
Text
</div>
<div class="rowflex">
<img src="//placekitten.com/60" style="min-width: 0;"/>
</div>
</div> In this scenario, we first have to compute the intrinsic width of the outer flex container, which is based on the intrinsic width contributions of its descendants, which ends up being the intrinsic width of the image (or the text, if it's wider). Then we can do layout in the outer flex container, which ends up stretching Then, when we do layout inside the inner flex container, we may start out by asking for its intrinsic width. With your change, we would find that it now has a significantly larger intrinsic width than what we initially thought, because its image flex item would suddenly have a larger intrinsic width contribution (due to being stretched to ~180px and transferring that through to its intrinsic size contribution, per your new rule). I'm not sure what the outcome of this would be, but I think What do you think about this sort of scenario and what this change means for it, @davidsgrogan ? |
Yeah, there is weird interplay in this case. Your guess on the outcome is right: The new behavior for this case is weird. I think it's consistent with the rest of CSS though*, and the funkiness comes from flex's 2-pass-edness. I'm not sure what alternate behavior we'd want to specify. Like, suppose we remove the stretching from your example above by adding these two lines: .rowflex {
align-items: flex-start;
}
img {
height: 100%;
}
So, in sum, this case is weird to me too, but after I went through (1) and (2), I think it's just an unfortunate side effect of making block sizes affect intrinsic inline sizes, which seems like a positive change overall. * We're making replaced-with-aspect-ratio elements' intrinsic sizes in one dimension obey the transferred constraints from the other dimension (First note in https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes). This new flex behavior falls out of that change. |
This means the stretched cross-size transfers to the main-size via aspect-ratio, doesn't it? I think this behavior may violate the spec. In flex algo step 11: "Determine the used cross size of each flex item", it says:
I blamed the flexbox spec, and found the edit came from https://lists.w3.org/Archives/Public/www-style/2012Oct/0781.html |
Yes, the stretched cross-size is transferring to the main-size via aspect ratio. But not because of step 11 (not even in layout at all). Just via 9.8.1, which takes effect before step 11. I take the note at step 11 to mean that when you stretch at step 11, you don't stretch the main axis through the aspect ratio. It's the same reason that both Chrome and Firefox make this image 100x100 instead of 16x100. And what fantasai talks about in w3c/csswg-drafts#5060 (comment) , emphasis mine:
So, assuming 9.8.1 is in effect during intrinsic width calculation, just like it's in effect in layout before step 11, then the new behavior is just another consequence of 9.8.1.
Good find. The case there is similar to dholbert's, and argues for the existing rendering. But 9.8.1 effectively does what that thread said the spec shouldn't do:
, which is in contrast to the current spec and fantasai's linked comment. |
So I think for this specific case we might need to update our implementation a little. What happens here (in layout when determining sizes) is that the column flexbox tells the row flexbox that children shouldn't resolve against its height (we call this concept the "initial block-size is indefinite"). I quickly made this change in a local build and for this specific case it renders the same as before. (@davidsgrogan this is the local change: https://chromium-review.googlesource.com/c/chromium/src/+/2878647 ) One thing to note is that when working through these scenarios with stretching we often start with "what would a |
Ah, now I see the point. An aspect-ratio flex item's width can be different depending whether its height is stretched or not. This is all about whether the stretched item's width can contribute to the flex container's intrinsic width or not. A single-line row flex container's width surely can affect the flexible item's final width. Thanks for the explanation. |
@bfgeek and I talked offline. We plan to continue with the overall change I described in comment 0 above. But Ian is going to commit the change referenced two comments up that forces items in column flexboxes to treat their block size as indefinite when calculating the flexbox's intrinsic inline sizes. I don't think there's spec support for this forced indefiniteness but it seems to be good because (a) it makes us ignore the We'll add a .tentative test for the forced indefiniteness. |
The new tests seem reasonable to include, with two hesitations: * table-as-item* -- We explicitly decided to exclude tables as a focus area from compat2021. Making Blink pass these `flexbox/table-as-item` tests required a bunch of work in the tables code. Maybe we shouldn't penalize Webkit for an area that we agreed to deprioritize? Maybe we should exclude any test that any engine fails? * flexbox-min-width-auto-00{5,6} -- Currently all engines pass, but we think the tests are wrong and Blink plans to change them as long as the behavior change is web compatible (see web-platform-tests/wpt#28805) @dholbert, thoughts on the updated test list? Any we should remove from the original list because they are invalid?
* table-as-item* -- We explicitly decided to exclude tables as a focus area from compat2021. Making Blink pass these `flexbox/table-as-item` tests required a bunch of work in the tables code. Maybe we shouldn't penalize Webkit for an area that we agreed to deprioritize? Maybe we should exclude any test that any engine fails? * flexbox-min-width-auto-00{5,6} -- Currently all engines pass, but we think the tests are wrong and Blink plans to change them as long as the behavior change is web compatible (see web-platform-tests/wpt#28805) * Remove table*item tests that >=1 engines fail.
Hi flex-interested people (@svillar @aethanyc @dholbert @bfgeek),
Blink is going to change how stretched aspect-ratio flex items ("images") contribute to a flex container's intrinsic width. When an image has a stretched height such that it qualifies as definite via flex 9.8.1, we'll now pass the height through the aspect ratio to find the image's intrinsic contribution.
E.g. https://jsfiddle.net/dgrogan/mjptyxe5/ :
All engines currently show a 60x100 green rectangle. Blink will soon (hopefully Chrome 92, which goes to stable mid-July) show 100x100.
This affects css/css-flexbox/flexbox-min-width-auto-00{5,6}.html
I think we are going to leave those tests unchanged and mark them failing in our tree until we know this change is web compatible.
Thoughts? Concerns?
The text was updated successfully, but these errors were encountered: