Dense photo gallery
- Input
- Thumbnails quadrados, muitos itens
- Expected output
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
A low minimum packs more columns per row, good for dense grids of small images.
responsive CSS grid without media queries
The combination `grid-template-columns: repeat(auto-fit, minmax(220px, 1fr))` is probably the most reused line of CSS in modern card grids. It tells the browser to fit as many columns of at least 220px as the available width allows, and stretch the leftover ones to fill the space, all recalculated automatically on every resize, without a single `@media`.
A low minimum packs more columns per row, good for dense grids of small images.
A higher minimum guarantees comfortable reading room inside each card.
Percentage is computed against the container's full width. `fr` distributes whatever space is left after fixed-size tracks (px, minmax minimum) are already reserved, which is why `1fr 200px` lets the first column take everything not used by the 200px track, something percentage alone can't express.
For card grids, auto-fit is almost always the right choice: when there are few items, it lets the existing columns stretch to fill the row. auto-fill keeps empty "ghost" columns reserved, which leaves a handful of cards bunched to the left with blank space beside them.
Yes, but with one caveat: since the column count is dynamic, a fixed `grid-column: span 2` can behave unexpectedly at widths where only 1 column exists. Test the featured item at the extreme widths before locking in the span.
gap accepts any CSS unit, including `clamp()`. A `gap: clamp(0.75rem, 2vw, 1.5rem)` lets the spacing between cards grow slightly on larger screens, keeping the same "no media query" logic as the rest of the grid.
Click an item to select it, drag to move it, or use the corner handle to resize it.
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}CSS is generated locally in your browser.