auto-fill vs auto-fit

repeat(auto-fill, …) leaves empty tracks in place; repeat(auto-fit, …) collapses them so the remaining items stretch — the crux of media-query-free responsive grids.

Also known as: repeat(auto-fill)repeat(auto-fit)
···
html
<div class="stage" id="stage">
  <div class="row">
    <b class="lbl">auto-fill</b>
    <div class="grid fill"><div class="cell">1</div><div class="cell">2</div><div class="cell">3</div></div>
  </div>
  <div class="row">
    <b class="lbl">auto-fit</b>
    <div class="grid fit"><div class="cell">1</div><div class="cell">2</div><div class="cell">3</div></div>
  </div>
</div>
css
.stage{width:44%;min-width:150px;max-width:92%;border:2px dashed var(--muted);border-radius:10px;padding:10px;
  transition:width 2.8s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;gap:10px;box-sizing:border-box}
.stage.wide{width:92%}
.row{display:flex;flex-direction:column;gap:4px}
.lbl{font:700 clamp(9px,1.7vmin,11px)/1 ui-monospace,monospace;color:var(--muted)}
.grid{display:grid;gap:5px}
.fill{grid-template-columns:repeat(auto-fill,minmax(34px,1fr))}
.fit{grid-template-columns:repeat(auto-fit,minmax(34px,1fr))}
.cell{height:26px;border-radius:6px;display:grid;place-items:center;color:#fff;font-weight:800;font-size:11px}
.fill .cell{background:var(--accent)}
.fit .cell{background:var(--accent-3)}
js
const stage = document.getElementById('stage');
setInterval(() => stage.classList.toggle('wide'), 2400);

grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)) creates as many tracks as fit the container's width — even with only 3 items, a wide container might get 6 or 8 tracks, and the empty ones still claim their share of the 1fr space. The 3 real items stay near their minmax minimum, and the rest of the row is taken up by invisible empty tracks.

auto-fit builds the same tracks, but then collapses any track with nothing in it down to zero width. All that freed space flows to the tracks that actually hold items, so they share the 1fr and stretch to fill the full container width.

The rule of thumb: use fill when you want empty tracks to remain (so items keep a fixed size), use fit when you want the items you do have to fill the row. Once there are enough items to wrap onto multiple rows anyway, the two behave identically — the difference only shows up when there's leftover horizontal space.

When to use

Want a handful of cards to hug the left on a wide screen? Use auto-fill. Want them to fill the row completely? Use auto-fit — the default choice for most card grids.