Skip to content

CSS Grid Generator

Split blocks, drag the gaps to resize, swap and name areas or start from a preset — and copy clean CSS with grid-template-areas.

How it works

Split a block in two, drag the gap to resize, repeat — like panes in a code editor. Under the hood the generator collects every edge of every block, turns the distances between them into columns and rows, and writes the layout with grid-template-areas — the most readable way to describe a page layout in CSS:

css
.layout { display: grid; grid-template-columns: 240px 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: "header header" "sidebar main" "footer footer"; } .header { grid-area: header; }

Each string is one row, each word is one column. The browser reads it like a picture of the layout.

The rules the generator follows

  • Areas must be rectangles. grid-template-areas can't describe an L-shape — the whole declaration becomes invalid and is ignored. Splitting a block in two always gives two rectangles, so whatever you build here is valid.
  • Empty cells are dots. A . (or several, like ...) marks a cell that belongs to no area. You won't see them here: every block is an area, so the grid has no holes.
  • Every row needs the same number of columns. A row with a missing column also invalidates the whole value.
  • Names are CSS identifiers. Letters, digits, - and _, not starting with a digit.

Track sizes

  • fr shares the free space: 1fr 3fr gives the second column three times as much of what's left after fixed tracks and gaps. The generator turns your percentages into the smallest whole fr numbers — 25% / 75% becomes 1fr 3fr. Edges that almost line up (within 1.5%) are treated as one line, so you don't get a useless 1fr sliver between two rows that end a pixel apart.
  • Swap a track for a fixed size when you need one: 240px 1fr for a sidebar that doesn't stretch.
  • auto sizes the track to its content — the usual choice for headers and footers.
  • minmax(200px, 1fr) never shrinks below 200px but grows like 1fr.
  • A plain 1fr is really minmax(auto, 1fr): it won't shrink below its content's minimum size. If a long word or a wide table pushes a column wider than expected, use minmax(0, 1fr).

Responsive layouts

Areas make breakpoints cheap: keep the HTML, change only the picture. Turn on mobile stack and the generator adds this for you:

css
@media (max-width: 640px) { .layout { grid-template-columns: 1fr; grid-template-rows: none; grid-template-areas: "header" "sidebar" "main" "footer"; } }

grid-template-rows: none matters: without it the desktop row sizes (1fr 3fr …) would still apply to the first rows of the stacked layout. With none, every row sizes to its content.

The areas stack in HTML order. You can reorder them here for a different picture, but remember that the visual order changes and the DOM order doesn't — screen readers and keyboard focus still follow the HTML, so keep the source order meaningful.