Bismillâh, kardeşim. Every e-commerce platform's homepage is a grid of products that somehow knows your screen size. On Amazon it's four columns. On your phone it's one. On an iPad portrait it's two, on landscape three. Most people assume there's a thick responsive framework doing the work. There isn't. There's one line of CSS. Let's learn it today.

The one line

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}

Read it as a sentence: "create as many columns as fit, each one at least 180 px wide but willing to grow to fill the remaining space." Resize the demo window. At 400 px you see one column. At 620 px, two. At 820 px, three. At 1200 px, four. No media queries, no framework, no JavaScript.

Why auto-fit is the magic word

Grid has two fit modes: auto-fill and auto-fit. They behave identically most of the time, but they diverge when the grid is wider than all its content needs:

  • auto-fill creates empty columns to fill the remaining space. Your four products sit at the left, three ghost columns stretch to the right.
  • auto-fit collapses the empty columns, so the real products stretch to fill the row. Each card grows with the screen, no ghosts.

For a product catalog, always reach for auto-fit. Empty-column ghosts just look like your shop is missing stock.

Why minmax(180px, 1fr) is the other magic word

minmax sets two bounds. The column can shrink down to 180 px, no less. It can grow up to 1fr, which is "one share of the remaining space." If two columns fit on a 560 px wide grid, each gets 280 px. If three fit, each gets 186 px. The grid picks the densest arrangement where every column is at least 180 px wide.

Pick the first number based on how small you want a card to be before it still reads well. For shop cards with images and a title, 180-240 px is the sweet spot. For compact chips or avatars, 80-140 px. For articles or long-form cards, 320 px.

Matching gap and padding

gap is spacing between grid cells; use it, don't fake it with margins. Margins double up (each card has a margin, so between two cards there's 2x margin) and break cleanly when you need alignment. gap applies exactly once between cells and never on outer edges. This is why page-level padding stays neat around a gridded section.

.grid {
  gap: clamp(0.6rem, 2vw, 1.2rem);
  padding-inline: clamp(1rem, 4vw, 2rem);
}

Here I reach for clamp twice so both the gap and the outer padding scale with the viewport. On a phone the page is tight and compact; on a wide desktop there's breathing room.

Consistent card heights

Grid children stretch to the tallest item's height by default. This is usually fine, but if one card has a very long product title, every card in that row grows to match. Two fixes:

  • Clip the title. white-space: nowrap; overflow: hidden; text-overflow: ellipsis; keeps every title on one line with a fade-out ellipsis.
  • Clamp the description. -webkit-line-clamp: 2 combined with display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden limits a paragraph to two lines in every browser.

Capping the grid for ultra-wide screens

At 2000 px wide, minmax(180px, 1fr) gives you eleven columns. Usually that's too many. Two simple fixes:

/* Option A: hard cap on the grid container */
.grid { max-width: 1200px; margin-inline: auto; }

/* Option B: cap the column count by picking a larger min */
.grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

Option A keeps the grid centered on very wide screens; option B keeps cards readable by never going below 280 px. You rarely need both.

Tricks worth carrying

  • aspect-ratio on the image container stops the whole card from jumping when the real product photo loads. Set it to the ratio of your actual photos (1.25 for landscape-ish, 1 for square, 0.8 for portrait).
  • Touch the card, not the button. Make the <a href> wrap the whole card, not just the title. Users on phones rarely aim precisely at the link text.
  • Skeleton placeholders belong in the grid itself. While products load, render six gray blocks of the same shape. No layout shift when the real data arrives.
  • :nth-child(even) lets you alternate card backgrounds for a "newspaper" feel without tagging products. Use sparingly; it reads clearer when products are visually similar.

Takeaways

  1. One line: grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)).
  2. Use gap, not margins, inside grids.
  3. Use auto-fit, not auto-fill, for product catalogs.
  4. Cap the grid's max-width on ultra-wide screens.

Next post: "Filter products as you type, with ten lines of JavaScript."

Ship clean grids, kardeşim. Simple is the most responsive layout.