CSS grid generator
Generated in your browser · nothing is uploaded
Builds a display: grid rule with repeat() columns, rows and gaps, previewed as real boxes so you can see what the numbers do.
How to use the css grid generator
The column size is the choice that decides whether a grid behaves, and 1fr is not automatically the right answer. An fr is a share of the leftover space, but the specification defines 1fr as shorthand for minmax(auto, 1fr), which means the track has a minimum of auto and will refuse to shrink below the content inside it. Put one long unbroken string, a wide table or an image with no max-width into such a column and the whole grid pushes past its container. That single detail is the most common grid bug there is. minmax(0, 1fr) sets the floor to zero and the columns behave, at which point the content overflows the column instead, where overflow: hidden or a min-width: 0 on the item catches it. Both of those sizes are in the dropdown here, so the difference is a click apart on real content.
The other two sizes repay a moment of experimenting for the same reason. min-content shrinks a track to the widest thing that cannot be broken, usually the longest word. max-content grows it to the width the content would take if it never wrapped at all. Neither is a layout you would usually ship, but seeing them side by side explains what auto and fr are negotiating between.
What this generator writes is a fixed grid: repeat(3, 1fr) means three columns, at every viewport width, until you change it. The genuinely responsive pattern is a hand edit away and repays memorising: repeat(auto-fill, minmax(220px, 1fr)) fits as many columns of at least 220px as the width allows and shares whatever is left between them, reflowing with no media queries at all. Substitute auto-fit and the only difference appears when you have fewer items than the row could hold: auto-fit collapses the empty tracks to nothing and the items you do have stretch to fill the row, while auto-fill keeps the empty tracks and leaves the gap. Neither is better; a search-results page with one result looks strange under auto-fill and a calendar looks wrong under auto-fit.
One last thing the rule here writes explicitly is the row count. grid-template-rows: repeat(2, auto) sizes exactly two rows. Give the grid more items than two rows of columns can hold and the extras land in implicit rows, which take their size from grid-auto-rows and default to auto regardless of what the explicit rows say. Grids grow along that axis quietly, which is usually what you want and occasionally a surprise.
What people use it for
- Getting a fixed card grid written out correctly the first time
- Finding out why a grid is overflowing its container
- Setting a row gap and a column gap to different values
- Seeing what min-content and max-content actually do to a column
- Writing repeat() rather than listing every track by hand
- Comparing 1fr against minmax(0, 1fr) on real content
- Working out the starting point for a responsive grid you then edit
- Explaining the fr unit to somebody who has only used percentages
Questions
Because 1fr is really minmax(auto, 1fr), so the column will not shrink below its content. Switch to minmax(0, 1fr) and the track can finally give way.
A share of the space left over after fixed tracks and gaps are taken out. Three columns at 1fr each get a third of the remainder, which is why gaps do not have to be subtracted by hand the way percentages do.
Because a percentage does not know about the gap. Three columns at 33.33% plus two gaps overflows; three at 1fr does not, because the gaps are removed before the shares are worked out.
Row gap first, then column gap, which is the reverse of what most people guess. A single value sets both.
Write repeat(auto-fill, minmax(220px, 1fr)) as the column size. It fits as many 220px-minimum columns as it can and shares the remainder. This generator writes a fixed count, so that is an edit you make after copying.
Nothing at all until you have fewer items than the row could hold. Then auto-fit collapses the empty tracks and the items stretch to fill the row, while auto-fill keeps them and leaves the space empty.
Ask what a nearly empty row should look like. A gallery with two photos usually looks better stretched, so auto-fit. A grid where the column positions carry meaning, like a calendar, wants auto-fill.
A min-content track shrinks to the widest unbreakable thing in it, usually the longest word. A max-content track widens to what the content would take with no wrapping at all.
They go into implicit rows created automatically. Those take their height from grid-auto-rows rather than from the explicit grid-template-rows, and default to auto.
Grid when you are positioning things in two dimensions at once and the tracks matter. Flexbox when a single row or column needs to distribute space among whatever it is given.
Yes, and usually should. The repeat() notation applies one size to every track it generates, so a layout with a fixed sidebar and a flexible main area is written out as grid-template-columns: 240px minmax(0, 1fr) instead.
They do, and they resolve against the content box of the grid in that axis. A percentage row gap resolves against the height, which is often not what people intend.
The same minmax(auto, 1fr) default. Besides switching to a zero minimum, overflow-wrap: anywhere on the item lets the word itself break, which is often the better fix for prose.
Yes. The boxes above are laid out by the declaration printed below them, so the gaps and track sizes you see are the ones you are copying.
Up to twelve, which covers the great majority of page layouts and matches the count most design systems settled on. Beyond that, write the repeat() by hand.