Skip to content

[css-sizing] Stretch-fitting inline size next to floats. #4028

Open

Description

@mstensho

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?

<style>
  .outerfloat { float:left; width:100px; height:100px; background:blue; }
  .stf { overflow:hidden; width:fit-content; background:yellow; }
  .spacer { float:left; width:300px; height:10px; }
</style>
<div style="width:500px;">
  <div class="outerfloat"></div>
  <div class="stf">
    <div class="spacer"></div>
    <div class="spacer"></div>
  </div>
</div>

Should the yellow box fit to the right of the yellow box, or go below, and use the entire width of its containing block?

Activity

  1. fantasai commented on Jun 11, 2019

    @fantasai
    Collaborator

    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.

  2. yisibl commented on Jul 17, 2024

    @yisibl
    Contributor

    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

  3. yisibl commented on Sep 24, 2024

    @yisibl
    Contributor

    @dholbert Based on your description here[1], you're leaning towards stretch = 100% right?

    [1]https://bugzilla.mozilla.org/show_bug.cgi?id=1920634

  4. dholbert commented on Sep 24, 2024

    @dholbert
    Member

    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.

  5. bfgeek commented on Sep 24, 2024

    @bfgeek

    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.

    @dholbert - Does this make sense?

  6. bfgeek commented on Sep 24, 2024

    @bfgeek

    Re-reading Elika's initial response, I think my long-winded response is saying the same thing :P .

  7. dholbert commented on Sep 24, 2024

    @dholbert
    Member

    @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.

  8. bfgeek commented on Sep 24, 2024

    @bfgeek

    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.

    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).

  9. dholbert commented on Sep 24, 2024

    @dholbert
    Member

    Good to know. I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1920816 to look into a similar refactoring on our side.

  10. Loirooriol commented on Sep 25, 2024

    @Loirooriol
    Contributor

    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).

  11. yisibl commented on Sep 25, 2024

    @yisibl
    Contributor

    @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;">

    image

  12. bfgeek commented on Sep 25, 2024

    @bfgeek

    @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.

  13. 12 remaining items

  14. moved this to Newer FTF agenda items in CSSWG January 2026 meetingon Jan 25, 2026
  15. moved this from Newer FTF agenda items to Tuesday afternoon in CSSWG January 2026 meetingon Jan 26, 2026
  16. moved this from Tuesday afternoon to Skipped things in CSSWG January 2026 meetingon Jan 28, 2026
  17. moved this from Skipped things to Wednesday morning in CSSWG January 2026 meetingon Jan 28, 2026
  18. css-meeting-bot commented on Jan 28, 2026

    @css-meeting-bot
    Member

    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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions