I've read a lot of tutorials about CSS flex boxes and CSS grids, but frankly I just can't figure out how to do this simple(?) thing.
All I want is for the elements in a container to all be as wide as the widest element.
I don't want them to fill up the whole width of the container, just all grow to the maximum width. Can that be done with CSS?
Consider this HTML:
<div class="container">
<button>a normal button</button>
<button>tiny</button>
<button>a really, really, really wide button</button>
</div>
That produces something like this:
What I want is something like this, where they're all the width of that widest button:
I DON'T want them to just stretch out to fill the width of the page:
Can this be done? If so, what would be the CSS for the above HTML?
The width property sets the width of an element. The width of an element does not include padding, borders, or margins! Note: The min-width and max-width properties override the width property.
The width property in CSS specifies the width of the element's content area. This “content” area is the portion inside the padding, border, and margin of an element (the box model). In the example above, elements that have a class name of . wrap will be 80% as wide as their parent element.
Using width, max-width and margin: auto; The element will take up the specified width, and the remaining space will be split equally between the two margins: This <div> element has a width of 500px, and margin set to auto.
Site-wide elements are the items that appear on every page, and are identical on every page. Site-wide elements are categorized into Header, Navigation and Footer regions.
Yes. This can be done with pure CSS.
Here's a simple solution:
.container {
display: inline-grid;
grid-template-columns: 1fr 1fr 1fr;
}
<div class="container">
<button>a normal button</button>
<button>tiny</button>
<button>a really, really, really wide button</button>
</div>
Here's how it works:
Grid Layout provides a unit for establishing flexible lengths in a grid container. This is the fr
unit. It is designed to distribute free space in the container (and is somewhat analogous to flex-grow
).
However, the Grid spec provides for a particularly unique behavior when the container's width / height is dynamic (e.g., display: inline-grid
, in this case).
In such cases, the fr
unit will compute the max-content
of each grid item. It will then take the maximum value it finds and use that as the 1fr
length for all items on the track.
That results in grid items that share the width of the widest item in the row.
Strange, but true.
It's also why a layout with equal height rows is possible with Grid (but not flexbox).
Here's the relevant section in the spec:
7.2.3. Flexible Lengths: the
fr
unit...
When the available space is infinite (which happens when the grid container’s width or height is indefinite), flex-sized (
fr
) grid tracks are sized to their contents while retaining their respective proportions.The used size of each flex-sized grid track is computed by determining the
max-content
size of each flex-sized grid track and dividing that size by the respective flex factor to determine a “hypothetical1fr
size”.The maximum of those is used as the resolved
1fr
length (the flex fraction), which is then multiplied by each grid track’s flex factor to determine its final size.
Here is a solution using CSS Grid working with any number of buttons:
div.container {
display: inline-grid;
grid-auto-columns: 1fr;
}
div.container button {
grid-row: 1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With