CSS Grid Generator

Build a grid with real cells: equal columns, a responsive auto-fit track list, or your own template, with a spanning feature cell.

Enable JavaScript to change the grid; the CSS below is for the defaults.

Columns

Equal columns for a fixed grid, auto-fit for one that reflows without media queries.

With auto-fit, this is the width below which a column drops to the next row.

Any track list: lengths, fr units, minmax(), repeat(). Used when the mode above is custom.

auto sizes rows to their content. A length here writes grid-auto-rows instead.

Left empty it matches the gap above. A number here writes the two values separately.

Justify items

Where each item sits inside its own cell, horizontally.

Align items
Auto flow

dense backfills the holes a spanning cell leaves, at the cost of reordering.

1
2
3
4
5
6
7
grid.css
.grid-container {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 16px;
}

Build a grid against real cells: a fixed number of columns, a responsive track list that reflows on its own, or your own template.

How to use

  1. Choose how the columns are made. Equal columns for a fixed grid, auto-fit for one that reflows without a single media query, custom when you need 240px 1fr.
  2. With auto-fit, set the minimum column width. That number is the width at which a column gives up and moves to the next row.
  3. Set the gap. Grid had gap before flexbox did, and it applies between tracks, never around the outside.
  4. Turn on the spanning cell to see how a feature tile works, and what holes it leaves. row dense backfills those holes.
  5. Copy the CSS. Anything at its default is left out.

Example

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

That is a responsive grid with no breakpoints: as the container narrows, columns drop off one at a time when they can no longer be 240 pixels wide.

Pitfalls

  • 1fr is not the same as minmax(0, 1fr). A bare 1fr has an automatic minimum, so one long word, a pre block or a wide image pushes the whole grid past its container. Equal columns here are written with the zero minimum for that reason.
  • auto-fit and auto-fill differ only when there are more tracks than items. auto-fit collapses the empty ones, so three cards fill the row; auto-fill keeps them, so three cards stay a third wide.
  • A percentage gap resolves against the container’s own size, not the track size, which makes it behave unlike a percentage anywhere else.
  • justify-items and align-items position items inside their cells. To move the whole grid inside a larger container you want justify-content and align-content.
  • grid-auto-rows only sizes the rows grid creates implicitly. Rows you name in grid-template-rows ignore it.
  • row dense reorders content to fill holes, so the visual order stops matching the DOM order. That is a real accessibility problem for anything interactive.
  • A span larger than the track count is clamped to the grid, silently. A cell set to span 4 in a 3 column grid spans 3.
  • Nesting a grid inside a grid item is fine, but the inner grid’s tracks have nothing to do with the outer ones. subgrid is what connects them, and it needs Firefox 71, Safari 16 or Chrome 117.

Compatibility

CSS grid is supported unprefixed by every browser in use since 2017, including repeat(), minmax(), auto-fit, auto-fill and gap. subgrid is newer: Firefox 71, Safari 16, Chrome 117. The old -ms-grid syntax in Internet Explorer is a different specification and is not emitted here. The tool runs entirely in your browser.

Frequently asked questions

Grid or flexbox?
Grid when rows and columns both matter, or when you want a track list. Flexbox for one direction, and for content that should size itself.
How do I make a responsive grid without media queries?
repeat(auto-fit, minmax(240px, 1fr)). Change the 240 to taste; that is the whole technique.
Why is my grid wider than the page?
Almost always a bare 1fr track with unbreakable content in it. Use minmax(0, 1fr).
How do I place an item in a specific cell?
grid-column: 2 / 4 and grid-row: 1. The spanning cell here uses the span form, which is relative rather than absolute.
What about named areas?
grid-template-areas is excellent for page-level layout and is a different shape of tool: you draw the layout as text. This generator covers track lists and spans.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.