CSS grid generator

Set the columns and rows, then drag across the cells to place an item — or start from a preset. The CSS updates as you go — copy it with line numbers or as grid-template-areas, together with the HTML or as Tailwind CSS classes. For cards that wrap on their own, switch to Auto-fill cards.

Columns
3
Rows
3
header
sidebar
main
footer

Drag across empty cells (or tap one) to add an item. Edit or remove items in the list.

Column sizes
Row sizes

Use 1fr, 200px, 25%, auto, min-content or minmax(100px, 1fr).

Items
    CSS
    .grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(3, 1fr);
      gap: 16px;
    }
    
    .header {
      grid-area: 1 / 1 / 2 / 4;
    }
    
    .sidebar {
      grid-area: 2 / 1 / 4 / 2;
    }
    
    .main {
      grid-area: 2 / 2 / 3 / 4;
    }
    
    .footer {
      grid-area: 3 / 2 / 4 / 4;
    }
    HTML
    <div class="grid">
      <div class="header"></div>
      <div class="sidebar"></div>
      <div class="main"></div>
      <div class="footer"></div>
    </div>
    Tailwind CSS
    <div class="grid grid-cols-[repeat(3,_1fr)] grid-rows-[repeat(3,_1fr)] gap-4">
      <div class="col-start-1 col-end-4 row-start-1 row-end-2"><!-- header --></div>
      <div class="col-start-1 col-end-2 row-start-2 row-end-4"><!-- sidebar --></div>
      <div class="col-start-2 col-end-4 row-start-2 row-end-3"><!-- main --></div>
      <div class="col-start-2 col-end-4 row-start-3 row-end-4"><!-- footer --></div>
    </div>

    How CSS grid placement works

    A grid is a set of numbered lines. Three columns have four column lines: line 1 is the left edge, line 4 the right edge. An item says which lines it starts and ends on, so grid-area: 2 / 1 / 4 / 2 means row line 2 / column line 1 / row line 4 / column line 2 — rows 2 and 3 of the first column. That is the order the shorthand uses: row-start, column-start, row-end, column-end.

    The presets

    How we test it

    The CSS, HTML and Tailwind output is pasted, exactly as you would copy it, into Chrome for 304 different grids at a phone and a desktop size, and every item's position and size is measured (1,652 item boxes). Grids made of pixel and fr tracks must match the track maths above to half a pixel; the named-areas CSS must lay out exactly like the line-number CSS; and the Tailwind classes, compiled with Tailwind CSS 4.3.3, must lay out exactly like the plain CSS. Each preset must render the layout its description above promises, at three sizes. The auto-fill mode is checked the same way: 141 settings at 4 container widths (7,124 card boxes) must match the column-counting rule above, and the Tailwind version must match the CSS.

    Questions

    Why is 1fr sometimes wider than I set it?

    1fr never shrinks below its content's minimum width. A long word or a wide image keeps the column wide. Use minmax(0, 1fr) to let it shrink to nothing.

    Line numbers or named areas — which should I use?

    Named areas are easier to read and to rearrange in a media query: you change one grid-template-areas block and every item moves. Line numbers work for anything, including items that overlap on purpose.

    How do I make the grid responsive?

    Put a different grid-template-columns (and, with named areas, a different grid-template-areas) inside a @media rule. For cards that wrap on their own, switch to Auto-fill cards: it writes repeat(auto-fill, minmax(200px, 1fr)) with your minimum width, and needs no media query at all.

    auto-fill or auto-fit — what's the difference?

    Both fit as many columns as there is room for. When there are fewer cards than columns, auto-fill keeps the empty columns, so the cards stay their normal width; auto-fit collapses the empty columns to zero, so the cards stretch across the whole row. With enough cards to fill a row they look the same.

    What do the Tailwind classes need?

    Tailwind CSS v4 or v3.3+. Track sizes are arbitrary values in square brackets (spaces become underscores), gaps use the spacing scale where the pixel value is a multiple of 4, and each item gets col-start, col-end, row-start and row-end.

    Shaping the items too? Try the clip-path generator, or turn existing CSS into classes with the CSS to Tailwind converter.