CSS Grid Visualizer
Paste CSS. See the grid. Change it, and take the code back.
The only grid tool that reads CSS as well as writes it
Every other grid generator is write-only. You draw a layout, copy the code, and the moment that layout lives in a stylesheet the tool has nothing left to offer — the next change is back to counting line numbers in your head. This reads the CSS back, which makes the same editor a debugger for grids you did not write.
How to use it
-
Paste the CSS
Drop in the rule that has display: grid on it, along with the child rules and any media queries. A whole stylesheet is fine — everything that is not part of the grid is ignored.
-
Read the layout
The grid is drawn as areas on a canvas, one view per breakpoint. Drag the width ruler to see what the layout does at each media query.
-
Change it
Move an area, resize a track, add a breakpoint. It is the same editor as the generator, so everything works the same way.
-
Take it back
Copy the CSS out, or the HTML, Tailwind, React, Vue or Svelte version of it. The media queries are rewritten to contain only what actually differs.
What it reads
The container rule — display: grid, the track lists, the gaps — and the two ways
of placing children: a grid-template-areas map, or child rules using
grid-area, grid-column and grid-row. Both forms are
understood, including span counts and negative line numbers like
1 / -1. A child with display: none is read as "not rendered at this
width", which is exactly what it means.
Every @media (min-width: …) block becomes a breakpoint, in ascending order, and
the values cascade the way the browser cascades them: a query that only changes the columns
inherits everything else from the width below it. min-width in
em and the modern (width >= 900px) range syntax both work.
What it cannot do, and says so
It is a layout reader, not a CSS engine. It does not resolve custom properties, follow imports
or arbitrate specificity between two rules that fight over the same element. And
repeat(auto-fill, …) has no fixed column count by definition — the number depends
on the container at render time — so the editor shows a workable number of tracks and tells
you it did. Anything skipped is reported above the canvas rather than dropped quietly, because
a visualiser that silently loses half your layout is worse than one that refuses it.
Using it to debug
Two failures account for most broken grids, and both are visible the moment the layout is
drawn. The first is an area map whose rows have different lengths: that makes the whole
grid-template-areas declaration invalid, so the browser throws it away and the
layout falls back to auto-placement. The importer flags it instead of guessing.
The second is an item placed outside the tracks that exist — grid-column: 1 / 5
in a three-column grid. The browser creates implicit tracks to hold it, which is why the
layout looks right in one place and collapses in another. On the canvas the item is simply
past the edge of the defined grid, which takes about a second to spot.
It goes both ways
What comes out is not what went in — it is the same layout, re-emitted. Media queries carry only the properties that actually change at that width, item placements that are unchanged are not repeated, and the output is available as Tailwind, a React, Vue or Svelte component, or a shadcn-style compound component. Pasting a grid in and taking a tidier one out is a reasonable way to use this on its own.
If you would rather start from a layout than from code, the grid generator begins with a blank canvas and the layout pattern library has 46 of them ready to edit.
Frequently asked questions
How do I visualise CSS Grid code?
display: grid, together with its child rules and any media queries. The layout is drawn as areas on a canvas, one view per breakpoint, and you can drag the width ruler to see what happens at each media query.Does it read grid-template-areas or line numbers?
grid-area, grid-column and grid-row are read as line placements, including span counts and negative lines such as 1 / -1. A child with display: none is treated as not rendered at that width, which is what it means.Why does my grid look wrong in the browser but fine in the code?
grid-template-areas make the whole declaration invalid, so the browser discards it and falls back to auto-placement. Or an item is placed outside the tracks that exist — grid-column: 1 / 5 in a three-column grid — and the browser creates implicit tracks to hold it. Both are obvious once the layout is drawn.What happens to repeat(auto-fill, …)?
repeat() back when you copy the CSS out.