-
Notifications
You must be signed in to change notification settings - Fork 664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-sizing] Possible to reproduce a <div>
's width: auto
behavior on any element?
#7427
Comments
What about I think to test it in current implementations, you'll need to use |
@dbaron – Thank you for your response. Unless the implementation of |
I think the shrink-to-fit behavior of |
What happens here is that But in flex layout they have different meanings. You can then use Also, AFAIK Strictly speaking, I think what you want is a way for resolving But I'm not convinced that this is worth doing. It seems to me that e.g. if you turn the container into a flex container, then you can also make the button adapt to being a flex item. |
Thank you so much for the insightful response @Loirooriol.
That very well could be! I didn't realize that
Strangely, the "Browser compatibility" table doesn't have a "Supported in Block Layout" row, nor did I find the feature listed on caniuse.com. I would add that the problem isn't necessarily about "replaced" elements. As I mentioned in my (way too long) initial post, it affects
Definitely, there are multiple ways to achieve the desired flexibility by allowing some kind of communication between the component and its consumer (e.g. in terms of React: props or context; or in terms of pure CSS: parent class + direct child selector, custom property, etc.). But the point is that the consumer should not have to do anything IMO. There should be a way to make it "just work", like it does with other element types. |
Hello dear CSS Working Group people!
I spend a lot of time building UI components, and I always try to make them as flexible as possible, in the sense that they should adapt well to different contexts (and different contents, if they accept children), ideally on their own (i.e. with no changes to their HTML/CSS and without relying on any JS).
One reliable way I've found to achieve that is to make components "responsive" or "fluid" by default, meaning that they should behave basically like a block element: their width should stretch to their parent's width, unless they are in a context that dictates their width or makes them "shrink-to-fit" to their intrinsic width, like if they are a Flexbox or Grid child, or the child of a
position: absolute
element that doesn't have a width. That is quite easy to do by making the root element of each component a<div>
with no explicitwidth
(so it uses the default value ofauto
), making it behave exactly as I just described.That works, but in many cases, I would love the root element to be something other than
<div>
. For instance, if my component is a<button>
, I haven't managed to reproduce the above behavior without a wrapper<div>
(note: it doesn't have to be specifically a<div>
– other block-level elements like<section>
or even non-block elements like<span>
withdisplay: block
on them work as well – but<div>
makes the most sense semantically, since it's just a generic block container). That is because, unfortunately,width: auto
doesn't have the same behavior on all elements, even withdisplay: block
. For instance, a<button>
will "shrink-to-fit" its contents, as if it haddisplay: inline-block
or was inside a flex container or something (related issues: #3226, #6789). It's not just about<button>
or (semi-)replaced elements, though: notably,<table>
has the same problem.I have tried all those new intrinsic sizing keywords for the
width
property (min-content
,max-content
,fit-content
, andstretch
), but none of them seem to do what I want, which is to reproduce the behavior thatauto
has for block-level elements such as<div>
. I realize that the behavior I'm after is a mix between extrinsic and intrinsic sizing based on the context, but hopefully it makes sense to others.width: 100%
is also not an acceptable solution, as it doesn't behave the same asauto
in a Flexbox or Grid context: instead of shrinking-to-fit, the component would always stretch to the container's (or grid area's) width, or at least mess with the flex sizing algorithm (assuming it hasflex-basis: auto
and there are other flex items that don't wrap). Just to explain why I want the shrink-to-fit behavior, let's take the button example again. On a given page or screen size (e.g. mobile), maybe we want the button to be "full width" in its container (e.g. a sidebar), but on another page or screen size (e.g. desktop), maybe we want the same button component to be centered inside its container. With the shrink-to-fit behavior, that centered requirement becomes as simple as placing it in a<div style="display: flex; justify-content: center;">
. No need to change the button component itself; it adapts well to both contexts.Again, I do have a functional workaround, which is to wrap the
<button>
in a<div>
inside the component, and then setwidth: 100%
on the<button>
itself (it still shrinks-to-fit when desired/expected, because the parent<div>
does). However, I can't help but wonder if it would make sense to introduce a new keyword forwidth
that would reproduce the<div>
'swidth: auto
behavior for any element, including<button>
,<select>
,<input>
,<table>
, etc. Maybe I missed something and it's already possible, in which case, please let me know. :)Thank you for reading!
The text was updated successfully, but these errors were encountered: