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] Stretch-fitting inline size next to floats. #4028
The spec currently doesn't provide a size keyword to achieve this effect, but there used to be one named "fill-available", then renamed to "fill", "stretch" and/or "stretch-fit".
The behavior is partially defined, though, in level 3.
"The size a box would take if its outer size filled the available space in the given axis; in other words, the stretch fit into the available space, if that is definite."
Furthermore, the spec already refers to stretch-fit sizing as part of resolving fit-content, so my question is: How is stretch-fitting in the inline dimension affected by adjacent floats?
Interestingly enough, the answer varies: for boxes that establish an independent containing block, CSS2 says they fit in the remaining space after the float; for non-replaced blocks, the float is ignored. Probably fit-content and the stretch keyword should match this behavior, since it was their intention to provide a switch between the shrink-to-fit sizing and fill-available sizing behaviors in CSS2.
That's my leaning, yeah, based simply on what the spec currently says about stretch-fit sizing filling the containing block:
Stretch-fit sizing tries to set the box’s used size to the length necessary to make its outer size as close to filling the containing block as possible while still respecting the constraints imposed by min-height/min-width/max-height/max-width.
So I have (very) strong feelings 😀 that it should go beside the float.
Basically the nice thing about the new stretch keyword is that it explains the other half of width:auto.
In Blink, we never resolve an auto length, instead we coerce it to either fit-content or stretch length depending on the context.
E.g. In grid layout auto behaves as stretch for non-replaced elements, and fit-content for replaced.
For block layout the rules are a little more complex but basically: replaced, tables, floats, and some form controls are fit-content everything else is stretch.
For new formatting contexts with "auto-as-stretch", all engines today consider the available space for this calculation as adjusted for floats.
Basically I'd like to keep the invariant that engines can coerce auto to fit-content, or stretch. (Note this also becomes important for calc-size() FWIW).
If we don't go down this path to fully "explain" auto we'd need to introduce a new variant, e.g. stretch-respecting-floats that I'd prefer not to do.
From the web-developer perspective if we go with the "next-to-float" definition:
If they want to clear the float and take up the full content-box area they can just do clear: both.
If they want to make something that is auto as fit-content to stretch next to a float they can just do width: stretch.
(e.g. <input style="width: stretch">)
If we go with the "clears-floats" definition:
They aren't able to make something that is auto as fit-content stretch next to a float. 😢
The "next-to-float" definition is strictly more powerful for developers.
However, auto isn't always 100% identical to fit-content or stretch, because in Blink both fit-content and -webkit-fill-available allow the fixed table layout mode, but width: auto doesn't (see #10937 for details).
@yisibl - So this is because by default <input> is display: inline-block if you change it to display: block it'll switch behaviour to the block-level new formatting-context behaviour.
display: inline-block receives the full containing block available inline-size (e.g. https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13124 ). Its somewhat complex as to why this is, but basically things that sit in a linebox have different rules to a block-level new FC.
The CSS Working Group just discussed [css-sizing] Stretch-fitting inline size next to floats., and agreed to the following:
RESOLVED: Do what Oriol says here.
The full IRC log of that discussion
<fantasai> iank_: I'm fine resolving on what Oriol has said
<fantasai> iank_: This is about the `stretch` keyword. It's roughly like 100%, but not quite.
<fantasai> iank_: Question is what to do with floats
<fantasai> iank_: Our guiding principle is "what does auto do here?"
<fantasai> iank_: and for in-flow block-level independent formatting context, what auto does here is to avoid floats
<fantasai> iank_: Internally, Blink doesn't actually resolve with `auto`. We map it to `stretch` or `fit-content` and then resolve that
<fantasai> iank_: If we did something different we'd need to add a concept
<fantasai> iank_: 3rd point is, being replaced counts as an independent formatting context
<fantasai> iank_: Therefore replaced + stretch should avoid floats
<fantasai> iank_: If you're not an IFC, you fill your containing block. That's what width:auto does.
<fantasai> iank_: When you're an atomic inline box, you stretch to the CB
<fantasai> iank_: Their available space, they can always grow to their CB, because they will push the line box down past the float
<fantasai> iank_: We don't want to diverge fit-content and stretch having different available sizes
<fantasai> iank_: It's the weirdest part here, but consistent because of this logic.
<fantasai> fantasai: Great explanation, thank you!
<fantasai> PROPOSED: Do what Oriol says
<fantasai> fantasai: Agree with the principles, that's also what we think.
<fantasai> RESOLVED: Do what Oriol says here.
Activity
fantasai commentedon Jun 11, 2019
Interestingly enough, the answer varies: for boxes that establish an independent containing block, CSS2 says they fit in the remaining space after the float; for non-replaced blocks, the float is ignored. Probably
fit-contentand thestretchkeyword should match this behavior, since it was their intention to provide a switch between the shrink-to-fit sizing and fill-available sizing behaviors in CSS2.yisibl commentedon Jul 17, 2024
There is a 17-star issue in Chrome that relies on the CSSWG to resolve the specification as soon as possible.
https://issues.chromium.org/issues/41253915
yisibl commentedon Sep 24, 2024
@dholbert Based on your description here[1], you're leaning towards
stretch = 100%right?[1]https://bugzilla.mozilla.org/show_bug.cgi?id=1920634
dholbert commentedon Sep 24, 2024
That's my leaning, yeah, based simply on what the spec currently says about
stretch-fit sizingfilling the containing block:https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
I don't have especially strong feelings on this at the moment, though; if there are reasons to favor the other behavior, that's probably fine too.
bfgeek commentedon Sep 24, 2024
So I have (very) strong feelings 😀 that it should go beside the float.
Basically the nice thing about the new
stretchkeyword is that it explains the other half ofwidth:auto.In Blink, we never resolve an
autolength, instead we coerce it to eitherfit-contentorstretchlength depending on the context.E.g. In
gridlayoutautobehaves asstretchfor non-replaced elements, andfit-contentfor replaced.For block layout the rules are a little more complex but basically: replaced, tables, floats, and some form controls are
fit-contenteverything else isstretch.For new formatting contexts with "auto-as-stretch", all engines today consider the available space for this calculation as adjusted for floats.
Basically I'd like to keep the invariant that engines can coerce
autotofit-content, orstretch. (Note this also becomes important forcalc-size()FWIW).If we don't go down this path to fully "explain"
autowe'd need to introduce a new variant, e.g.stretch-respecting-floatsthat I'd prefer not to do.From the web-developer perspective if we go with the "next-to-float" definition:
clear: both.autoasfit-contentto stretch next to a float they can just dowidth: stretch.(e.g.
<input style="width: stretch">)If we go with the "clears-floats" definition:
autoasfit-contentstretch next to a float. 😢The "next-to-float" definition is strictly more powerful for developers.
@dholbert - Does this make sense?
bfgeek commentedon Sep 24, 2024
Re-reading Elika's initial response, I think my long-winded response is saying the same thing :P .
dholbert commentedon Sep 24, 2024
@bfgeek yup, that makes sense to me - thanks for the explanation!
I like the idea of explaining
autolengths in terms offit-content&stretch. If the Blink behavior gets us to that goal, that seems worthwhile.bfgeek commentedon Sep 24, 2024
FWIW when we realized this, we did a refactor, and it simplified our
autobehaviour significantly.(maybe I'll write a blog post about this one day).
dholbert commentedon Sep 24, 2024
Good to know. I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1920816 to look into a similar refactoring on our side.
Loirooriol commentedon Sep 25, 2024
However,
autoisn't always 100% identical tofit-contentorstretch, because in Blink bothfit-contentand-webkit-fill-availableallow the fixed table layout mode, butwidth: autodoesn't (see #10937 for details).yisibl commentedon Sep 25, 2024
@bfgeek Currently in Chrome,
overflow:hiddendoesn't keep the input behind the float element (we have to usedisplay: flow-root), is this as expected?bfgeek commentedon Sep 25, 2024
@yisibl - So this is because by default
<input>isdisplay: inline-blockif you change it todisplay: blockit'll switch behaviour to the block-level new formatting-context behaviour.display: inline-blockreceives the full containing block available inline-size (e.g. https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13124 ). Its somewhat complex as to why this is, but basically things that sit in a linebox have different rules to a block-level new FC.12 remaining items
css-meeting-bot commentedon Jan 28, 2026
The CSS Working Group just discussed
[css-sizing] Stretch-fitting inline size next to floats., and agreed to the following:RESOLVED: Do what Oriol says here.The full IRC log of that discussion
<fantasai> iank_: I'm fine resolving on what Oriol has said<fantasai> iank_: This is about the `stretch` keyword. It's roughly like 100%, but not quite.
<fantasai> iank_: Question is what to do with floats
<fantasai> iank_: Our guiding principle is "what does auto do here?"
<fantasai> iank_: and for in-flow block-level independent formatting context, what auto does here is to avoid floats
<fantasai> iank_: Internally, Blink doesn't actually resolve with `auto`. We map it to `stretch` or `fit-content` and then resolve that
<fantasai> iank_: If we did something different we'd need to add a concept
<fantasai> iank_: 3rd point is, being replaced counts as an independent formatting context
<fantasai> iank_: Therefore replaced + stretch should avoid floats
<fantasai> iank_: If you're not an IFC, you fill your containing block. That's what width:auto does.
<fantasai> iank_: When you're an atomic inline box, you stretch to the CB
<fantasai> iank_: Their available space, they can always grow to their CB, because they will push the line box down past the float
<fantasai> iank_: We don't want to diverge fit-content and stretch having different available sizes
<fantasai> iank_: It's the weirdest part here, but consistent because of this logic.
<fantasai> fantasai: Great explanation, thank you!
<fantasai> PROPOSED: Do what Oriol says
<fantasai> fantasai: Agree with the principles, that's also what we think.
<fantasai> RESOLVED: Do what Oriol says here.
[css-sizing-3] IFCs exclude floats when stretching #4028