You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-sizing][css-flexbox] It's false that stretch size behaves as stretch alignment #11784
When computing the size of the flex lines: height: stretch stretches against the containing block, while align-self: stretch doesn't stretch.
Once we know the size of the flex lines: height: stretch keeps stretching against the containing block, while align-self: stretch stretches against the line.
If the flex container doesn't have a definite height (remove height: 100px):
Gecko and Blink don't stretch height: stretch, neither when computing line sizes nor once we know their size. align-self stretches in the latter one:
WebKit does that thing of stretching all ancestors with indefinite size, in this case filling the window:
changed the title [-][css-sizing] It's false that `height: stretch` behaves as `stretch` alignment[/-][+][css-sizing][css-flexbox] It's false that `height: stretch` behaves as `stretch` alignment[/+]on Mar 10, 2025
Currently our behavior for flex items is to treat width/height:stretch as equivalent to width/height:100%, rather than equivalent to stretch alignment. This equivalency is correct in most other places, but differs here, as you point out. However, the equivalency is also broken in abspos, where %s resolve against the original CB size but stretch alignment (and width:auto) resolves against the IMCB; Chrome implements width/height:stretch to fill the IMCB, matching stretch alignment.
So, I'm inclined to say we should try and follow the spec's text. It's consistent with the behavior in all other locations, afaik, and presents a more useful behavior for this case. It does mean widening the delta between stretch and -webkit-fill-available, so there's potentially some compat risk, but I'd like to try for it if possible.
However, if it turns out this is an issue, I'm okay with resolving to match the 100% behavior in this case instead.
Note that making a stretch size match stretch alignment presumably means that fit-content should also stretch to the line, but clamping between min-content and max-content. This might introduce some compat risk, but probably fine.
Chrome implements width/height:stretch to fill the IMCB, matching stretch alignment.
changed the title [-][css-sizing][css-flexbox] It's false that `height: stretch` behaves as `stretch` alignment[/-][+][css-sizing][css-flexbox] It's false that `stretch` size behaves as `stretch` alignment[/+]on Mar 18, 2025
Thanks for the heads-up! No concerns from me on changing that testcase's expectations.
When I wrote that test, I don't think I was aware of the linked spec text (the text that gives stretch sizes special meaning in contexts where *-self alignment applies), and I was just thinking of stretch as being a fancy 100% similar to how @tabatkins described it above.
So while experimenting with implementing this we've come to the conclusion that its not true that align-self: stretch and width: stretch are always equal.
Specifically the difference comes from:
Determine the hypothetical cross size of each item by performing layout as if it were an in-flowblock-level box with the used main size and the given available space, treating auto as fit-content.
<!DOCTYPE html>
<div style="font: 16px monospace; width: 100px; height: 100px; border: solid 4px; display: flex; gap: 10px; flex-wrap: wrap; flex-direction: column;">
<div style="background: lime;">a b c </div>
<div style="background: lime;">a b c d e f g h i j k l m n o p q r s t u v w x y z</div>
</div>
When determining the line-cross-size of a wrapping flexbox (typically of a column flexbox) the given available-size is always the container available size.
In this stage width: auto becomes width: fit-content. The line-cross-size is calculated based on this fact.
Then when determining the final used cross size (the final layout of the flex-item) width: auto becomes width: stretch.
This comes from:
Determine the used cross size of each flex item. If a flex item has align-self: stretch, its computed cross size property is auto, and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line, clamped according to the item’s used min and max cross sizes. Otherwise, the used cross size is the item’s hypothetical cross size.
width: stretch doesn't have the ability to change, and hence can result in a different layout in these circumstances.
IMO I think this behaviour difference is fine/expected. I don't think we want to magically coerce stretch to fit-content in the cross-size determination step.
(Also note that passing an indefinite available size doesn't work as that'll make the width max-content instead of fit-content which is a sutble behaviour difference).
... is mostly true, but incorrect when it comes to flexbox for the above reason. (There are larger implications for any behaviour change away from this when we have things like min-width: stretch; width: fit-content for example).
In recent chrome canary we changed stretch to behave closer to align-self: stretch. Blink now mostly stretches cross-size:stretch to the line, not the container. But we arguably* don't completely follow the current spec, and think it's better behavior not to, as @bfgeek mentions above.
Our deviation from the current spec (and, as a corollary, our spec-change proposal) can be summed up as
If flex-line cross size is known, cross-size:stretch stretches to it
Otherwise (e.g. when computing the flex-line cross-size), cross-size:stretch stretches to the container width
Whereas the current spec arguably* requires
If flex-line cross size is known, cross-size:stretch stretches to it
Otherwise, cross-size:stretch behaves as fit-content with container cross size as available size
Blink's old behavior:
Blink's new behavior:
What the spec arguably* calls for:
In some of these flex items, the author asked to stretch, and the current spec arguably* says to match align-self:stretch, but that results in no stretching at all. We argue that not stretching when the author requested it is lame; we should give them some version of what they want when we can.
@dholbert@Loirooriol WDYT? Do you prefer Blink's "new" behavior, or the "spec" behavior?
PS: On mentions of arguably*: I say arguably, because there's actually an interpretation of the spec that dictates our proposed behavior already. Namely, emphasis added,
Otherwise, if used in an axis where percentage sizes can resolve to a definite value
Behaves as 100%, except it sizes the margin box regardless of the value of box-sizing.
When we are calculating the the flex-line cross-size, align-self doesn't apply! So we follow the 'Otherwise' 100% behavior. When we do so, the line ends up being the same width as the container, which has the same effect of stretching to the container in the end.
This wasn't discussed in detail, but I guess the resolution implies that align-self: stretch makes the automatic size be fit-content (instead of stretch) while the cross line size isn't known. Otherwise it would stretch to the container, breaking various WPT and possibly websites.
Activity
Loirooriol commentedon Feb 26, 2025
BTW, same for a column flexbox:
With
width: min-content; max-width: 100px:[-][css-sizing] It's false that `height: stretch` behaves as `stretch` alignment[/-][+][css-sizing][css-flexbox] It's false that `height: stretch` behaves as `stretch` alignment[/+]Loirooriol commentedon Mar 10, 2025
Maybe I could have merged this into #11293. But this one is more about flexbox, that one about abspos.
tabatkins commentedon Mar 18, 2025
I chatted with @bfgeek about this today.
Currently our behavior for flex items is to treat width/height:stretch as equivalent to width/height:100%, rather than equivalent to stretch alignment. This equivalency is correct in most other places, but differs here, as you point out. However, the equivalency is also broken in abspos, where %s resolve against the original CB size but stretch alignment (and
width:auto) resolves against the IMCB; Chrome implements width/height:stretch to fill the IMCB, matching stretch alignment.So, I'm inclined to say we should try and follow the spec's text. It's consistent with the behavior in all other locations, afaik, and presents a more useful behavior for this case. It does mean widening the delta between
stretchand-webkit-fill-available, so there's potentially some compat risk, but I'd like to try for it if possible.However, if it turns out this is an issue, I'm okay with resolving to match the 100% behavior in this case instead.
Loirooriol commentedon Mar 18, 2025
Note that making a stretch size match stretch alignment presumably means that
fit-contentshould also stretch to the line, but clamping between min-content and max-content. This might introduce some compat risk, but probably fine.False, see #11293
[-][css-sizing][css-flexbox] It's false that `height: stretch` behaves as `stretch` alignment[/-][+][css-sizing][css-flexbox] It's false that `stretch` size behaves as `stretch` alignment[/+]davidsgrogan commentedon Apr 23, 2025
Heads up @dholbert , this issue is talking about changing
stretchin the cross axis direction so that it resolves to the flex line's available space, not to the flex container's available space. If we do this, it would directly contradict your test assertion at https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/external/wpt/css/css-sizing/stretch/stretch-block-size-001.html;l=189-191;drc=910dc12bbc0595ea727c435b8298998ccc53e965WDYT?
dholbert commentedon Apr 25, 2025
Thanks for the heads-up! No concerns from me on changing that testcase's expectations.
When I wrote that test, I don't think I was aware of the linked spec text (the text that gives
stretchsizes special meaning in contexts where*-selfalignment applies), and I was just thinking ofstretchas being a fancy100%similar to how @tabatkins described it above.bfgeek commentedon Apr 25, 2025
So while experimenting with implementing this we've come to the conclusion that its not true that
align-self: stretchandwidth: stretchare always equal.Specifically the difference comes from:
https://drafts.csswg.org/css-flexbox-1/#algo-cross-item
For example:
https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13715
When determining the line-cross-size of a wrapping flexbox (typically of a column flexbox) the given available-size is always the container available size.
In this stage
width: autobecomeswidth: fit-content. The line-cross-size is calculated based on this fact.Then when determining the final used cross size (the final layout of the flex-item)
width: autobecomeswidth: stretch.This comes from:
https://drafts.csswg.org/css-flexbox-1/#algo-stretch
width: stretchdoesn't have the ability to change, and hence can result in a different layout in these circumstances.IMO I think this behaviour difference is fine/expected. I don't think we want to magically coerce
stretchtofit-contentin the cross-size determination step.(Also note that passing an indefinite available size doesn't work as that'll make the width
max-contentinstead offit-contentwhich is a sutble behaviour difference).I think that then the part of the sizing spec:
https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
... is mostly true, but incorrect when it comes to flexbox for the above reason. (There are larger implications for any behaviour change away from this when we have things like
min-width: stretch; width: fit-contentfor example).davidsgrogan commentedon May 7, 2025
In recent chrome canary we changed stretch to behave closer to
align-self: stretch. Blink now mostly stretchescross-size:stretchto the line, not the container. But we arguably* don't completely follow the current spec, and think it's better behavior not to, as @bfgeek mentions above.Our deviation from the current spec (and, as a corollary, our spec-change proposal) can be summed up as
cross-size:stretchstretches to itcross-size:stretchstretches to the container widthWhereas the current spec arguably* requires
cross-size:stretchstretches to itcross-size:stretchbehaves asfit-contentwith container cross size as available sizeRevisiting Oriol's example in #11784 (comment): (live):
Blink's old behavior:



Blink's new behavior:
What the spec arguably* calls for:
In some of these flex items, the author asked to stretch, and the current spec arguably* says to match
align-self:stretch, but that results in no stretching at all. We argue that not stretching when the author requested it is lame; we should give them some version of what they want when we can.@dholbert @Loirooriol WDYT? Do you prefer Blink's "new" behavior, or the "spec" behavior?
PS: On mentions of arguably*: I say arguably, because there's actually an interpretation of the spec that dictates our proposed behavior already. Namely, emphasis added,
When we are calculating the the flex-line cross-size, align-self doesn't apply! So we follow the 'Otherwise' 100% behavior. When we do so, the line ends up being the same width as the container, which has the same effect of stretching to the container in the end.
18 remaining items
Bug 1970019 [wpt PR 52919] - [stretch] Add more flex tests, a=testonly
Bug 1970019 [wpt PR 52919] - [stretch] Add more flex tests, a=testonly
Bug 1970019 [wpt PR 52919] - [stretch] Add more flex tests, a=testonly
Bug 1970019 [wpt PR 52919] - [stretch] Add more flex tests, a=testonly
Bug 1970019 [wpt PR 52919] - [stretch] Add more flex tests, a=testonly
Loirooriol commentedon Aug 7, 2025
Blink shipped successfully (implemented in https://chromium-review.googlesource.com/c/chromium/src/+/6493160)
Tests: web-platform-tests/wpt#52674, web-platform-tests/wpt#52919, web-platform-tests/wpt#54203
Servo: servo/servo#38526
layout: Let `stretch` on flex item cross size stretch to the line (#3…
Loirooriol commentedon Aug 9, 2025
This wasn't discussed in detail, but I guess the resolution implies that
align-self: stretchmakes the automatic size befit-content(instead ofstretch) while the cross line size isn't known. Otherwise it would stretch to the container, breaking various WPT and possibly websites.[css-flexbox-1] Clarified that the used cross size of an item is reca…
[css-sizing-3][editorial] Added a note about Flexbox actually being s…