CSS Grid Builder
Set the number of columns and rows, pick a track size for each, and copy the resulting grid CSS.
About the CSS Grid Builder
Each column and row gets its own track-size dropdown, so mixing fixed pixel columns with flexible fr columns or an auto row is as simple as picking from the list. The numbered cells above are a real display:grid box driven by those exact grid-template-columns and grid-template-rows values, so the preview always matches the copied code.
What the fr unit actually means
The fr (fraction) unit is unique to CSS Grid and doesn't map onto anything else in CSS. It represents a share of whatever space is left over after every fixed-size track (pixels, percentages, content-based auto tracks) has already claimed its space. A row of 1fr 1fr 1fr splits all available space into three equal parts, but 1fr 2fr 100px first reserves exactly 100px for the third column, then splits whatever remains between the first two columns at a 1:2 ratio. This is why fr-based layouts stay proportionally balanced as the container resizes, while a fixed-pixel-only grid would either leave empty space or overflow.
Why fr plays more nicely with gap than percentages do
If you size grid tracks with percentages, the browser doesn't automatically know to shrink those percentages to make room for your gap value, you can end up with a grid that's technically wider than its container once the gaps between tracks are added on top. fr units don't have this problem: the grid layout algorithm subtracts the total gap space from the container's width first, and only then divides whatever's left among the fr tracks. That's part of why fr became the standard recommendation for flexible grid tracks rather than percentages, the math around spacing just works correctly without any manual adjustment.
How the numbered cells fill the grid automatically
Notice that this tool never explicitly places any of the numbered cells into specific grid positions, it just creates a plain list of child elements and lets the browser's default grid auto-placement algorithm handle the rest. That algorithm fills cells in row-major order, left to right along the first row, then wraps to the start of the next row, continuing until it runs out of explicit tracks or children. This default behavior is what makes basic grid layouts so simple to build: as long as you define the track structure, dropping content in without manual positioning "just works" in a predictable reading-order sequence.
A design choice: track selections survive when you change the count
Increasing the column count from 3 to 5 doesn't reset your first three columns back to a default, this tool specifically remembers each track's previously chosen size and reapplies it, only filling brand-new tracks with the 1fr default. That avoids a frustrating pattern common in simpler builders, where bumping a count field wipes out sizing work you'd already done on the existing tracks.
What this builder doesn't cover
This tool always writes out every track explicitly, real-world grid CSS often uses the repeat() function instead, for example repeat(3, 1fr) instead of typing 1fr 1fr 1fr three times, which becomes especially useful for grids with many identical tracks. It also doesn't expose named grid lines, the grid-template-areas shorthand for naming and visually laying out named regions in your CSS, or the minmax() function for tracks that need both a size floor and ceiling. For a straightforward fixed-track grid, this tool covers the common case well, but more advanced named-area layouts still need to be hand-written.
Column and row caps are a deliberate UI limit, not a CSS one
The number inputs cap at 8 columns and 6 rows purely so the visual editor stays usable and legible on screen, real CSS Grid places no meaningful limit on track count. If your actual layout needs more tracks than these caps allow, generate the closest structure here, copy the CSS, and extend the grid-template-columns or grid-template-rows value manually with additional track sizes.
Frequently Asked Questions
What does the fr unit actually represent in a grid track?
fr stands for "fraction" and represents a share of the space left over after every fixed-size track (pixels, percentages, auto) has already claimed its portion. 1fr 2fr splits the remaining space in a 1:2 ratio, and the ratio stays proportional as the container resizes.
Why is fr recommended over percentages for flexible grid tracks?
The grid layout algorithm automatically subtracts the total gap space before dividing the remainder among fr tracks, so spacing math works correctly without adjustment. Percentage-based tracks don't automatically account for gap, which can make the grid overflow its container once gaps are added.
How does the tool decide where each numbered cell goes in the grid?
It doesn't explicitly position any cell, it relies on the browser's default grid auto-placement algorithm, which fills cells in row-major order (left to right, then wrapping to the next row) automatically based on the defined track structure.
Does changing the column or row count reset my existing track sizes?
No, this tool specifically preserves each track's previously selected size when you increase or decrease the count, only new tracks default to 1fr. This avoids losing sizing work you've already done on existing columns or rows.
Can this tool generate grid-template-areas or use the repeat() function?
No, it always writes out each track explicitly rather than collapsing repeated values with repeat(), and it doesn't expose named grid lines, grid-template-areas, or minmax(). For straightforward fixed-track grids it works well, but more advanced named-area layouts need to be added by hand.
Is the gap value applied to both rows and columns?
Yes, this tool uses the unified gap shorthand property, which sets equal spacing between both rows and columns simultaneously. If you need different horizontal and vertical spacing, you'd split it into separate row-gap and column-gap values in the copied CSS.