I have a row of items of arbitrary width. They are centered within the container (note white space on the left and right sides of the red container):
Sometimes the container gets smaller than the width of all items:
When this happens, I want the items in the end to wrap to the next row like this:
It is very imporant for me that each row's content must be left-aligned, but the grid as a whole must be centered:
Initially, I tried implementing it with FlexBox. After a lot of frustration and hair pulling, I've learned that this is impossible witn FlexBox: https://stackoverflow.com/a/32811002/901944
Another answer on the same page suggests using CSS grid instead of flexbox.
CSS grid produces a slightly different result, but that also suits me:
Here's the code that makes it work:
.red-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
justify-content: center;
}
This code contains a lot of keywords that I don't understand: grid-template-columns
, repeat
, auto-fit
, minmax
and max-content
. I tried reading up on them and failed. None of guides and API docs explicitly explain how this particualr combination works. MDN docs are way too short and cryptic.
What I specifically struggle with is this 210px
magic number. Why is it necessary? (Erm, I know it's necessary because how the spec is designed, but this does not help me understand.)
The sizes of items in my grid are arbitrary, so I can't use a fixed value. Also, setting this fixed value makes the result slightly off: small items grow and large items overflow the container.
What I essentially want is:
grid-template-columns: repeat(auto-fit, minmax(min-content, max-content));
but that rule is recognized by browsers as faulty.
I've stumbled upon this answer that explains that using both min-content
and max-content
together is forbidden by the spec in this context. The answer's suggested solution is... to use Flexbox!
The loop has closed. I'm back to where I started, expect that I'm now lacking hair on my head for another round.
How to do I center my grid while left-aligning each row's content, with items having arbitrary widths?
Here's a boilerplate to fiddle with for your convenience: https://jsbin.com/vuguhoj/edit?html,css,output
The container can be resized by dragging it by the bottom-right corner.
PS No display: inline
and float: left
please.
.page {
border: 1px solid black;
overflow: hidden;
resize: horizontal;
max-width: 500px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(max-content, 50px));
justify-content: center;
}
.item {
border: 1px solid black;
margin: 1px;
}
<div class="page">
<div class="grid">
<div class="item">
Foofoofoo
</div>
<div class="item">
Bar
</div>
<div class="item">
BazBaz
</div>
<div class="item">
QuuxQuuxQuux
</div>
</div>
</div>