The difference between auto-fill
and auto-fit
is that the latter collapses the empty columns.
But after by adding an item that spans all columns auto-fit
breaks and starts behaving like auto-fill
. I can’t find this behavior anyway in the specs. I fill it’s just bad implementation.
Is there a way to prevent it?
.auto-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))
}
.auto-fill {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
div > div {
aspect-ratio: 1;
background-color: gold;
border: 1px solid black;
}
h2 {
grid-column: 1 / -1;
}
<h1>repeat(auto-fit)</h1>
<div class="auto-fit">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<h1>repeat(auto-fill)</h1>
<div class="auto-fill">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<h1>repeat(auto-fit) with</h1>
<div class="auto-fit">
<h2>element spanning all columns</h2>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
2
Answers
The behavior you’re observing with auto-fit collapsing empty columns when a spanning element is added is indeed expected according to the CSS Grid specification. When using auto-fit, the grid will create as many tracks as possible while maintaining the defined minimum and maximum sizes. When a spanning element is added, it effectively occupies one or more tracks, causing the grid to adjust by collapsing the empty columns.
If you want to prevent this behavior and keep the grid tracks consistent even when spanning elements are added, you can use a combination of auto-fill, minmax, and max-content for the grid-template-columns property.
By using max-content, you ensure that each track will be as wide as necessary to fit the widest content within it. This prevents the collapsing of empty columns when a spanning element is added.
Because of you break the natural behavior of the
auto-fit
keyword value with thespan
keyword. When you spaning an element, thegrid
will create some new columns and other grid-items will behave as if there were some columns there.If you want to distribute this space between other items, you can follow this way:
Note: I changed some HTML elements to make the changes clearer.