Skip to content

[css-sizing] How to shrink to fit the width? #191

Open

Description

@yisibl

In this demo: http://jsbin.com/weqapufoyi/edit?html,css,output

demo

Because span float will automatically wrap, how to make the parent element shrink to the "Expectation" effect.

Can we add a new width/height value(e.g. width: auto-shrink), or already have other solutions?

spec: https://drafts.csswg.org/css-sizing/#width-height-keywords

cc @dholbert @tabatkins @fantasai

Activity

  1. SebastianZ commented on Jun 15, 2016

    @SebastianZ
    Contributor

    I think the best would be to adjust fit-content (in combination with max-width/max-height) and fit-content() accordingly to shrink automatically to the size of the content.

    Sebastian

  2. yisibl commented on Jun 15, 2016

    @yisibl
    ContributorAuthor

    @SebastianZ That would be best.

  3. tabatkins commented on Jun 22, 2016

    @tabatkins
    Member

    No, fit-content() won't work here. fit-content is "try to be max-content size, clamped by min-content and the specified limit" (or in the case of the fit-content keyword, clamped above by the available space). So using fit-content() will still make it the full size with empty space, as shown in the first example. You can see this behavior today in floats - create a float containing a few very long words, and when they break, the float doesn't "tightly wrap".

    Tight wrapping has been discussed in the past, but has never made it in yet.

  4. fantasai commented on Aug 2, 2016

    @fantasai
    Collaborator

    On 06/22/2016 02:10 AM, Tab Atkins Jr. wrote:

    Tight wrapping has been discussed in the past, but has never made it in yet.

    See discussion at https://www.w3.org/mid/54DAAD2C.6060704@inkedblade.net

    ~fantasai

  5. vasilisvg commented on Feb 17, 2017

    @vasilisvg

    I have the same issue on one of my sites, as I tried to explain here. And today the CSSWG Twitter account told me that it’s been discussed here on Github. Hurray! I was wondering, is there any progress on this?

  6. fantasai commented on Feb 17, 2017

    @fantasai
    Collaborator

    No progress yet, though we're glad to have your use cases tracked here. :) I think the blocker here will be largely the difficulty for implementations in doing something relatively difficult and expensive, so seeing where it's needed is helpful to justify the effort.

  7. Nadya678 commented on Feb 16, 2018

    @Nadya678

    Please add this option. I also need it. JS solution is complicated because during resizing window there must be made additional steps...

  8. benface commented on Nov 21, 2018

    @benface

    I love that some problems like this one still don't have a solution with today's CSS. Does it represent a challenge (cyclic dependencies)? Does it lack use cases / demand from developers?

    Here's a use case I had today: https://codepen.io/benface/pen/WYMMPo

    I don't want the underline to go past the text. Easy when the text doesn't wrap (a simple display: flex; on the container takes care of that), but impossible when it does.

    I'll be following this one for sure.

  9. 27 remaining items

  10. tkent-google commented on Jul 22, 2026

    @tkent-google
    Contributor

    The Chrome Layout Team has written an explainer for this feature, and we plan to build a prototype based on it.

    Regarding the syntax, rather than introducing a new keyword for the width property, we believe it would be better to introduce a new property that modifies the behavior of existing keywords.

    • Property Name: max-content-sizing
    • Values: auto | shrink-to-fit
  11. kizu commented on Jul 22, 2026

    @kizu
    Member

    @tkent-google Wow, great to see some work planned on this!

    I think separate property makes sense, and it is nice that flex is also included from the start.

    My quick answers to the questions in the explainer:

    Naming of the property and its keywords.

    I'll need to sit more on that one: naming is difficult :D

    How to handle containers containing float:right elements

    I think it could be ok to make them expand to the current auto width, but I wonder if we need to think about text-align here? For example, if we would have text-align: right and float: left, it might be the same issue? And same with text-align: center and any floats.

    Although, I wonder if it would be possible to still shrink things a bit, if it is possible to calculate the “available space” between every line box and the closest float on every side, which could allow us to know the max distance we could shrink in that direction.

    Should expand the width for overflowing content?

    Can you elaborate on this? I imagine this would mean expanding the box to go around the longest line, but without performing line-breaking again, so effective “available” space for the lines will stay? If so, that sounds nice. Not sure about a default behavior, maybe more like a separate keyword, where you could use only it or alongside the shrink-to-fit?

  12. 1jj commented on Jul 27, 2026

    @1jj
    * Property Name: `max-content-sizing`
    * Values: `auto | shrink-to-fit`
    

    I assume defaulting to shrink-to-fit is what most authors would prefer (and also expect, until reality proves them wrong).

    Did you bother to estimate how much real breakage such a change would cause?
    Fixing such breakage by inserting a single CSS rule should be trivial.

    Is this also a performance issue?

  13. tkent-google commented on Jul 28, 2026

    @tkent-google
    Contributor

    @kizu

    I think it could be ok to make them expand to the current auto width, but I wonder if we need to think about text-align here? For example, if we would have text-align: right and float: left, it might be the same issue? And same with text-align: center and any floats.

    Although, I wonder if it would be possible to still shrink things a bit, if it is possible to calculate the “available space” between every line box and the closest float on every side, which could allow us to know the max distance we could shrink in that direction.

    I guess text-align will have no issues. We can compute the shrink-to-fit width before applying text-align.

    Yeah, it might be possible to compute remaining space in each lines, and subtract the minimum one from the container width.

    Can you elaborate on this? I imagine this would mean expanding the box to go around the longest line, but without performing line-breaking again, so effective “available” space for the lines will stay? If so, that sounds nice. Not sure about a default behavior, maybe more like a separate keyword, where you could use only it or alongside the shrink-to-fit?

    I supposed a case where a long word overflows the available width. e.g.

    <div style="width:100px">
      <div style="width:fit-content; max-content-sizing:shrink-to-fit">
        LongLongLongWordExceeding100px
      </div>
    </div>
    <!-- The inner DIV should expand the width to contain the word? -->

    It might not be a blocker for the initial version of the feature.

    @1jj

    Is this also a performance issue?

    Yes. The new mode would be much slower than the current behavior, so I don't think it should be the default.

  14. Loirooriol commented on Jul 28, 2026

    @Loirooriol
    Contributor
  15. tkent-google commented on Jul 28, 2026

    @tkent-google
    Contributor

    @Loirooriol
    Let's discuss the details of the functionality here. I disabled "Issues" of the explainer.

  16. Loirooriol commented on Jul 28, 2026

    @Loirooriol
    Contributor

    You could have let me copy the issues before removing them. At least I still had one open.

    max-content-sizing should inherit to anonymous blocks

    I think that adding a block-level child to a block container which only had inline-level contents (which will then be wrapped in an anonymous block) should not radically change the sizing. The anonymous block should inherit max-content-sizing.

    Or maybe make it an inherited property in general?

    circular definition

    If the container is an inline formatting context, max-content inline size would be the widest line content wrapped within the fit-content inline size.

    The fit-content inline size uses the max-content inline size as an input, so this in inherently circular.

  17. LeaVerou commented on Jul 29, 2026

    @LeaVerou
    Member

    I think I like the idea of an inherited property that can just be set on the root and be done with. I cannot think of any single use case where we don't want shrinkwrapping, so the only reason this is not the default is compat, right?

    (if there are actual use cases, my answer would be different)

  18. kizu commented on Jul 29, 2026

    @kizu
    Member

    @LeaVerou
    I cannot think of any single use case where we don't want shrinkwrapping, so the only reason this is not the default is compat, right?

    Shrinkwrapping will change how things look — I think visually it can create a very different effect compared to not shrinkwrapping, where multiple elements in a column would not have the same widths. The page’s and components’ design might support this, but also might not.

    This might be similar to how the text-wrap: balance can’t be the default — while often it helps, in many other cases it can create visually awkward text. Shrinkwrapping will help there, but I am certain that in many cases this could create actual visual issues.

    One note: once this is prototyped somewhere, it will be pretty easy to verify this by going to some complex pages and adding * { max-content-sizing:shrink-to-fit } (or whatever it will be), and checking how the page looks with or without this change.

    Edit: Although, maybe it will be fine, given this will only work with the fit-content/max-content cases… But would be great to check this on real pages for sure.

  19. Dan503 commented on Jul 29, 2026

    @Dan503

    I'm not sure if this would be within scope, but I think this would be a great way to make 1fr behave like minmax(0, 1fr)with much cleaner syntax.

    . elem {
      max-content-sizing:shrink-to-fit;
      /** 3 columns guaranteed to all be 1/3 of width no matter the content inside */
      grid-template-columns: 1fr 1fr 1fr;
    } 

    The equivalent:

    . elem {
      /** 3 columns guaranteed to all be 1/3 of width no matter the content inside */
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    } 

    This might be adding too much functionality to the one property.

  20. LeaVerou commented on Jul 29, 2026

    @LeaVerou
    Member

    This might be similar to how the text-wrap: balance can’t be the default — while often it helps, in many other cases it can create visually awkward text. Shrinkwrapping will help there, but I am certain that in many cases this could create actual visual issues.

    But this doesn't affect wrapping itself.

    One note: once this is prototyped somewhere, it will be pretty easy to verify this by going to some complex pages and adding * { max-content-sizing:shrink-to-fit } (or whatever it will be), and checking how the page looks with or without this change.

    That would only validate that compat is a problem, which I never questioned. These use cases did something to work around the lack of shrinkwrapping, and their workarounds don't necessarily play well with real shrinkwrapping.


    I'd love for us to come up with a way to limit the number of CSS properties we introduce for these types of flags. E.g. what if we call it intrinsic-sizing so that it has some room to grow? It could even include interpolate-size as a longhand.

  21. Loirooriol commented on Jul 29, 2026

    @Loirooriol
    Contributor

    I think this would be a great way to make 1fr behave like minmax(0, 1fr)

    That's completely unrelated to max-content sizing

    what if we call it intrinsic-sizing so that it has some room to grow?

    I wouldn't do this now, because we still don't have plans for other things that can be controlled by this. If anything, intrinsic-sizing could be added later as a shorthand.

    It could even include interpolate-size as a longhand

    interpolate-size is completely unrelated to intrinsic sizing determination.


    Anyways, before discussing possible extensions, it's important to have an idea of how this is going to work. Because I still don't get how this is supposed avoid the inherent circularity. Is it something like this?

    1. Compute tentative max-content size, using current algorithm
    2. Compute tentative fit-content size, using current algorithm
    3. Lay out using tentative fit-content size
    4. Widest line determines final max-content size, and from there, final fit-content size

    But that still doesn't seem properly defined, since the max-content size is typically needed before resolving the size of the containing block, so we don't know the fit-content size at (2)...

  22. tkent-google commented on Aug 7, 2026

    @tkent-google
    Contributor

    @Loirooriol

    You could have let me copy the issues before removing them. At least I still had one open.

    Sorry for deleting the issues in the explainer so suddenly—that was rough on my part.

    max-content-sizing should inherit to anonymous blocks

    Regarding inheritance: while making it inherited is an option, the explainer currently specifies inherit: no and defines it as "This value alters the max-content inline size of the element and descendants" so that it affects the subtree, similar to how the zoom property works. We chose not to make it inherited because we thought it would allow for finer control—for instance, preventing it from automatically inheriting into new formatting contexts.

    circular definition

    You're completely right about the circular definition. That part should be rephrased to something like "the fit-content inline size when max-content-sizing is auto".

  23. Loirooriol commented on Aug 9, 2026

    @Loirooriol
    Contributor

    the explainer currently specifies inherit: no and defines it as "This value alters the max-content inline size of the element and descendants"

    OK, I missed that. But if it gets propagated to all descendants, I would just make it inherited instead? Or maybe non-inherited, but propagate it to some (but not all) descendants.

    preventing it from automatically inheriting into new formatting contexts

    Yeah, stopping the propagation at FC boundary is an option, but this is in conflict with the current explainer that just says "descendants".

    You're completely right about the circular definition. That part should be rephrased to something like "the fit-content inline size when max-content-sizing is auto".

    It still doesn't make sense to me, as I said in #191 (comment)

    The fit-content inline size requires the stretch inline size, which requires the final size of the containing block, which requires the final min/max-content sizes of the contents.

  24. Janneman84 commented on Aug 19, 2026

    @Janneman84

    In Flutter shrinkwrapping can be achieved setting a Text's textWidthBasis, which can be either parent or longestLine.
    This regards to whether the width of multiline text should assume either the parent's width or the width of the longest line.
    https://api.flutter.dev/flutter/painting/TextWidthBasis.html

    Maybe you could borrow some terminology here idk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions