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-fillcreates empty columns to fill the remaining space. Your four products sit at the left, three ghost columns stretch to the right. -
auto-fitcollapses 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: 2combined withdisplay: -webkit-box; -webkit-box-orient: vertical; overflow: hiddenlimits 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-ratioon 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
- One line:
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)). - Use
gap, not margins, inside grids. - Use
auto-fit, notauto-fill, for product catalogs. - Cap the grid's
max-widthon 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.