How To Tutorial menu

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

html
<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

css
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
}
PartMeaning
display: gridTurns 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: 20pxSpace 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

javascript
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

html
<!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 whenUse Flexbox when
You want rows and columns lined upItems flow in one line, like a menu
Building card galleries and page layoutsCentring things or spacing a toolbar

Exercise

Exercise

What does minmax(200px, 1fr) mean in the grid columns?

Learn How To with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp