How To Create a Responsive Cards Grid
Learn how to lay out cards in a grid that fits any screen, from a phone to a wide laptop.
Step 1: The HTML
Each card is an <article> with a coloured top area (in place of a photo), a title, a price and a button.
Example
<div class="grid">
<article class="card" data-cat="bags">
<div class="thumb" style="background:#f59e0b;"></div>
<h3>School Bag</h3>
<p class="price">Rs 2,500</p>
<button>Add to cart</button>
</article>
<!-- more cards -->
</div>Step 2: The CSS Grid
This one line does the magic:
Example
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
}| Part | Meaning |
|---|---|
display: grid | Turns on CSS Grid |
repeat(auto-fill, ...) | Make as many columns as will fit |
minmax(200px, 1fr) | Each column at least 200px, sharing extra space equally |
gap: 20px | Space between cards |
On a phone you get one column, on a tablet two or three, on a laptop four, and you never write a media query.
auto-fill keeps empty column slots when there are only a few cards. Use auto-fit if you want a few cards to stretch and fill the whole row.
Step 3: A Category Filter
A little JavaScript hides the cards that do not match the chosen category:
Example
function filter(cat) {
document.querySelectorAll(".card").forEach(function (card) {
card.style.display = (cat === "all" || card.dataset.cat === cat) ? "" : "none";
});
}Setting display to "" removes the inline style, so the card shows normally again.
The Complete Example
Example
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* { box-sizing: border-box; }
body { font-family: Arial, sans-serif; padding: 20px; background: #f9fafb; }
.filters button { background: white; border: 1px solid #059669; color: #059669; padding: 6px 14px; border-radius: 20px; margin: 0 6px 12px 0; cursor: pointer; }
.filters button.on { background: #059669; color: white; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; }
.card { background: white; border-radius: 10px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: transform 0.2s; }
.card:hover { transform: translateY(-4px); }
.thumb { height: 120px; }
.card h3, .card p { margin: 10px 14px; }
.price { color: #059669; font-weight: bold; }
.card button { margin: 0 14px 14px; background: #059669; color: white; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer; }
</style>
</head>
<body>
<h2>Ali's Stationery Shop</h2>
<div class="filters">
<button class="on" onclick="filter('all', this)">All</button>
<button onclick="filter('bags', this)">Bags</button>
<button onclick="filter('books', this)">Books</button>
</div>
<div class="grid">
<article class="card" data-cat="bags"><div class="thumb" style="background:#f59e0b;"></div><h3>School Bag</h3><p class="price">Rs 2,500</p><button>Add to cart</button></article>
<article class="card" data-cat="books"><div class="thumb" style="background:#2563eb;"></div><h3>Notebook Pack</h3><p class="price">Rs 600</p><button>Add to cart</button></article>
<article class="card" data-cat="bags"><div class="thumb" style="background:#db2777;"></div><h3>Laptop Bag</h3><p class="price">Rs 3,200</p><button>Add to cart</button></article>
<article class="card" data-cat="books"><div class="thumb" style="background:#7c3aed;"></div><h3>Story Book</h3><p class="price">Rs 450</p><button>Add to cart</button></article>
<article class="card" data-cat="books"><div class="thumb" style="background:#0891b2;"></div><h3>Drawing Book</h3><p class="price">Rs 300</p><button>Add to cart</button></article>
</div>
<script>
function filter(cat, btn) {
document.querySelectorAll(".card").forEach(function (card) {
card.style.display = (cat === "all" || card.dataset.cat === cat) ? "" : "none";
});
document.querySelectorAll(".filters button").forEach(function (b) { b.classList.remove("on"); });
btn.classList.add("on");
}
</script>
</body>
</html>Try it Yourself »Make the result window wider and narrower: the number of columns changes by itself.
Grid or Flexbox?
| Use Grid when | Use Flexbox when |
|---|---|
| You want rows and columns lined up | Items flow in one line, like a menu |
| Building card galleries and page layouts | Centring things or spacing a toolbar |
Exercise
Exercise
What does minmax(200px, 1fr) mean in the grid columns?
