A little help goes a long way. Find a tool/

Design

CSS Grid Generator

Free CSS grid generator: type 3 columns or a full track list like 200px 1fr auto, set rows and gap, preview the grid live, and copy the declaration block.

YOUR WORKSPACEFree to use. No sign-up.
—
Describe the tracks above.

Deep dive guides

A LITTLE CONTEXT · 4 MIN READCSS Grid: Tracks, fr Units, and Gaps

How css grid generator works

The columns field accepts two shapes. A plain number — 3 — becomes repeat(3, 1fr): three equal tracks sharing the free space. Anything else is treated as an explicit track list: 200px 1fr auto fixes a sidebar, lets the middle column flex, and sizes the last column to its content. The same grammar drives the rows field, which can be left empty so rows auto-flow to their content height.

Track lists validate against the vocabulary CSS actually supports: px, fr, em, rem, %, ch, and viewport units, plus the auto, min-content, and max-content keywords and the repeat(), minmax(), and fit-content() functions — so repeat(auto-fit, minmax(180px, 1fr)) passes straight through. Invalid tracks are rejected with the offending token named, instead of letting a typo silently collapse the layout.

The gap field emits gap: Npx, which spaces both columns and rows in one declaration. The preview applies the exact declarations to sample cells, so repeat counts and fr ratios are visible before anything is copied. Copy the block, then tune individual items with the flexbox generator's properties or your own overrides — grid owns the track skeleton, items own their place in it.

Frequently asked questions

What does 1fr mean?
One fr unit is one share of the space left over after fixed-size tracks and gaps are subtracted. In repeat(3, 1fr) every column gets an equal third of the leftover width; in 200px 1fr 2fr the fixed 200px column comes out first and the remaining space splits 1:2 between the other two.
When should I write repeat() instead of listing tracks?
Use repeat(n, 1fr) for equal tracks — shorter and obviously symmetric. List tracks individually when sizes genuinely differ, and use repeat(auto-fit, minmax(180px, 1fr)) when you want as many columns as fit, the responsive pattern that removes most media queries.
Why leave rows empty?
Without explicit rows, the grid creates implicit rows sized to their content, which is usually what card layouts want. Add a rows value when the vertical rhythm matters — repeat(2, 200px) for fixed-height rows, or minmax(100px, auto) to enforce a minimum while still growing.
What is the difference between gap and the old grid-gap?
None — grid-gap was the original name and gap is the standardized one, now shared with flexbox. Always write gap in new code. Like the old margins, gap only sits between tracks: no space is added at the container's edges, which keeps layouts flush without negative-margin fixes.