Open mstensho opened 5 years ago
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.
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
@dholbert Based on your description here[1], you're leaning towards stretch = 100%
right?
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.
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.
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:
clear: both
.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:
auto
as fit-content
stretch next to a float. 😢 The "next-to-float" definition is strictly more powerful for developers.
@dholbert - Does this make sense?
Re-reading Elika's initial response, I think my long-winded response is saying the same thing :P .
@bfgeek yup, that makes sense to me - thanks for the explanation!
I like the idea of explaining auto
lengths in terms of fit-content
& stretch
. If the Blink behavior gets us to that goal, that seems worthwhile.
I like the idea of explaining
auto
lengths in terms offit-content
&stretch
. If the Blink behavior gets us to that goal, that seems worthwhile.
FWIW when we realized this, we did a refactor, and it simplified our auto
behaviour significantly.
(maybe I'll write a blog post about this one day).
Good to know. I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1920816 to look into a similar refactoring on our side.
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).
@bfgeek Currently in Chrome, overflow:hidden
doesn't keep the input behind the float element (we have to use display: flow-root
), is this as expected?
data:text/html;charset=UTF-8,<!doctype html>
<div style="float:left; width:100px; height:100px; border:1px solid;">float: left</div>
<input type="text" style="overflow:hidden !important;
width:-webkit-fill-available; width: -moz-available; border: 2px solid blue;">
@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.
https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing https://drafts.csswg.org/css-sizing-3/#auto-box-sizes
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?
Should the yellow box fit to the right of the yellow box, or go below, and use the entire width of its containing block?