How to make a responsive card grid
Short answer
auto-fill and minmax() pick the number of columns by themselves:
<style>
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
.cards div { padding: 20px 12px; background: lavender; border-radius: 12px; text-align: center; }
</style>
<div class="cards">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
</div>How it works
Each card is at least 130 pixels wide. A row holds as many cards as fit, and the leftover space is shared equally among them. Make the browser window narrower — there will be fewer columns, and not a single media query is needed.
auto-fill or auto-fit
The difference shows when there are fewer cards than fit. auto-fill keeps empty columns, while auto-fit collapses them and the cards stretch across the full width:
<style>
.g { display: grid; gap: 8px; margin-bottom: 8px; }
.g div { padding: 10px; background: honeydew; }
</style>
<div class="g" style="grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));"><div>fill</div><div>fill</div></div>
<div class="g" style="grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));"><div>fit</div><div>fit</div></div>Common mistake
On a screen narrower than the minimum card width the grid overflows sideways: a column cannot get narrower than 130px. Guard against it with min() — minmax(min(130px, 100%), 1fr) — so on a very narrow screen a card takes the full width.
Functions used in this recipe
- grid-template-columns — The number and widths of the columns of a grid.
- repeat() — Repeats grid tracks instead of writing them out one by one.
- minmax() — A grid track size between a minimum and a maximum.
- gap — The gaps between items in flexbox and grid.