Build a CSS grid and see it as you type. Start from a preset, edit the track definitions directly, and copy the result. The four presets are responsive cards, a page layout, equal columns and a sidebar with content. The justify-items and align-items menus position each item inside its cell, and editing any track definition switches the preset to Custom.
Use fr instead of percentages for columns. fr is a fraction of the space left after fixed
tracks and gaps are taken out. 1fr 2fr splits the
remainder one third and two thirds, and it stays correct when you
change the gap. 50% 50% plus any gap overflows the
container, which is why old float and percentage layouts needed
a negative margin somewhere.
repeat(auto-fit, minmax(240px, 1fr)) gives you
columns at least 240px wide, as many as fit, sharing whatever
is left. That single declaration replaces the set of media
queries a card gallery used to need. It also responds to the
container width instead of the viewport, so it keeps working
inside a sidebar.
auto-fit and auto-fill differ only when
there are fewer items than columns: auto-fit collapses the empty
tracks so the items stretch, auto-fill keeps them and leaves a
gap. For a gallery that might hold two items, use auto-fit.
grid-template-areas lets you draw the layout in text and match each name to a child's grid-area. Rearranging at a breakpoint means redrawing the picture, which is easier to review than changed line numbers.
Grid items default to min-width: auto, so wide content pushes a track open and overflows. Write the track as minmax(0, 1fr) to let it shrink. Flexbox has the same trap.
grid-column: 1 / 3 spans from line 1 to line 3, which is two columns. A grid with 3 columns has 4 lines, so counting tracks instead of lines gives an off-by-one error.
grid-column: span 2 says what you mean without counting lines, and it still works after you add a column.
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
/* As many columns as fit at 240px or wider, sharing the remainder.
It responds to the container, not the viewport, so it keeps
working inside a sidebar where media queries would not. */
/* auto-fill instead of auto-fit keeps the empty tracks:
with two items you get two narrow cards and a gap,
rather than two cards stretching across. */ .page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"nav main"
"footer footer";
min-height: 100vh;
gap: 16px;
}
.page > header { grid-area: header; }
.page > nav { grid-area: nav; }
.page > main { grid-area: main; }
.page > footer { grid-area: footer; }
@media (max-width: 640px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "header" "nav" "main" "footer";
}
} To rearrange the layout, you redraw the picture, which is easier to review in a pull request than a set of changed line numbers.
/* Put two things in the same cell and stack them */
.hero {
display: grid;
}
.hero > * {
grid-area: 1 / 1; /* every child in row 1, column 1 */
}
/* The image and the caption now overlap, the grid still sizes
itself to the tallest child, and nothing is taken out of flow
the way position: absolute would. */ Use subgrid to align parts of sibling cards. It reached every major browser in 2023 and lets a child grid line up with its parent's tracks. For example, a row of cards can keep their headings, bodies and footers aligned across the row regardless of content length, which previously needed fixed heights or JavaScript.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
A fraction of the leftover space. 1fr 2fr splits the remaining width one third and two thirds, after any fixed tracks and gaps are subtracted. Use it instead of percentages, because 50% 50% plus a gap overflows the container.
Use repeat(auto-fit, minmax(240px, 1fr)). Columns are at least 240px wide, as many as fit, sharing the leftover space. That one line replaces the set of breakpoints a card gallery used to need, and the Responsive cards preset starts from it.
They differ only when there are fewer items than columns. auto-fit collapses the empty tracks so the items stretch to fill the row. auto-fill keeps them, leaving a gap on the right. For a gallery that might have two items, use auto-fit.
grid-template-areas lets you draw the layout as text, with each name matching a grid-area on a child. For example, "header header" above "nav main" puts a full-width header over two columns. To rearrange the layout at a breakpoint, you redraw the picture.
Grid items default to min-width: auto, so content wider than the track pushes it open. Set min-width: 0 on the item, or use minmax(0, 1fr) instead of 1fr for the track. Flexbox has the same trap.
justify-items positions each item horizontally inside its cell, and align-items positions it vertically. The default stretch fills the cell in that direction; start, center and end shrink the item to its content and place it at that side. Do not confuse them with justify-content and align-content, which move whole tracks around inside the container rather than items inside cells.
Set justify-items: center and align-items: center on the container, or the shorthand place-items: center, which sets both. Each item then shrinks to its content size and sits in the middle of its cell. In the generator, pick center in both menus and the two declarations appear in the CSS. If you only want one item centered, use justify-self and align-self on that item instead.
Custom means the tracks no longer match any preset. The menu switches to it on its own as soon as you type in grid-template-columns or grid-template-rows, and your edits are kept. Changing Gap or Items does not switch it, because those are not part of the track definition. Reset returns to Responsive cards and clears the justify-items and align-items menus back to stretch.
For one-dimensional rows, use the flexbox generator. Most pages use grid for the skeleton and flexbox inside the components. Style the cards with the box shadow generator.