CSS Grid Cheat Sheet

Free toolNo sign-up

Skim by property → click Copy to grab the declaration → click # to deep-link a specific value. Need to build a layout instead? Jump to the Grid Generator.

Canonical recipes

Six ready-to-paste Grid layouts you'll actually reach for at work. Copy the whole recipe; the property reference below covers what each declaration does if you want to tweak.

Holy Grail
header + nav + main + aside + footer
.page {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav main aside"
    "footer footer footer";
  min-height: 100vh;
  gap: 12px;
}
header { grid-area: header }
nav    { grid-area: nav }
main   { grid-area: main }
aside  { grid-area: aside }
footer { grid-area: footer }
Auto-fit card grid
responsive, no media queries
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}
/* Fits 4 cols at 1200px, 3 at 960px, 2 at 640px, 1 on mobile.
   Zero media queries. */
Bento (hero + support tiles)
one big tile + smaller ones
.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 120px;
  gap: 12px;
}
.bento > :first-child {
  grid-column: span 2;
  grid-row: span 2;
}
Fixed sidebar + fluid main
260px sidebar, main takes rest
.shell {
  display: grid;
  grid-template-columns: 260px 1fr;
  min-height: 100vh;
  gap: 0;
}
.shell > main { min-width: 0 }
/* min-width:0 lets long content shrink instead of
   overflowing the grid track. */
Photo gallery (masonry-lite)
grid-auto-flow: dense back-fills
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 120px;
  grid-auto-flow: dense;
  gap: 8px;
}
.gallery .wide  { grid-column: span 2 }
.gallery .tall  { grid-row: span 2 }
.gallery .large { grid-column: span 2; grid-row: span 2 }
Pricing table (3 tiers)
equal columns, elevated middle
.pricing {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  align-items: start;
}
.pricing > .featured {
  transform: scale(1.05);
  z-index: 1;
  box-shadow: 0 12px 24px rgba(0,0,0,0.1);
}

Live playground

Drag the sliders + flip the toggle to see the CSS + preview update live. Copy the exact declaration when it matches what you need. One playground, not per-row — experiment here, then use the property reference below to fine-tune.

1
2
3
4
5
6
7
8
9
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

Container properties

These properties go on the grid container (the parent of the items you're arranging).

display

Makes an element a grid container. Every property below only works on children of an element with display: grid (or inline-grid).

#display: grid
1
2
3
4
5
6
#display: inline-grid
before
1
2
3
after

grid-template-columns

Defines the columns of the grid. The most-used Grid property — 90% of layouts start here.

#grid-template-columns: 100px 100px 100pxSee real demo → CSS 2 Column Left Fixed Right Fluid
1
2
3
4
5
6
#grid-template-columns: 1fr 1fr 1frSee real demo → CSS Grid Two Column Layout
1
2
3
4
5
6
#grid-template-columns: repeat(3, 1fr)
1
2
3
4
5
6
#grid-template-columns: repeat(auto-fit, minmax(120px, 1fr))See real demo → CSS Auto-Fit Blog Archive Grid
1
2
3
4
5
6
#grid-template-columns: 200px 1fr 100pxSee real demo → CSS Grid Mega Menu Header
1
2
3
4
5
6

grid-template-rows

Defines the rows. Less common than columns — most layouts let rows auto-size to content, but explicit rows unlock bento layouts.

#grid-template-rows: 60px 100px 60pxSee real demo → Analytics KPI Card Grid
1
2
3
4
5
6
7
8
9
#grid-template-rows: 1fr 2fr
1
2
3
4
5
6
#grid-template-rows: minmax(60px, auto)
1
2
3

grid-template-areas

Named regions for readable layouts. Especially good for holy-grail + bento layouts where semantic names beat column/row math.

#grid-template-areas: "header header header" "nav main aside" "footer footer footer"See real demo → CSS Grid template-areas Dashboard Template
header
nav
main
aside
footer
#grid-template-areas: "hero hero small" "hero hero card"See real demo → Modern CSS Grid Bento Dashboard
hero
small
card

gap

Space between tracks. No outer margin, no :first/:last-child gymnastics, no negative-margin hacks.

#gap: 8px 24px
1
2
3
4
5
6
#row-gap: 20px; column-gap: 4px
1
2
3
4
5
6

justify-items

Aligns items horizontally within their cells. Default is stretch (each item fills its cell).

#justify-items: stretch
1
2
3
#justify-items: start
1
2
3
#justify-items: center
1
2
3
#justify-items: end
1
2
3

align-items

Aligns items vertically within their cells. Default is stretch.

#align-items: stretch
1
2
3
#align-items: start
1
2
3
#align-items: center
1
2
3
#align-items: end
1
2
3

justify-content

Aligns the WHOLE grid horizontally when tracks don't fill the container. Only kicks in when the grid is narrower than its container.

#justify-content: start
1
2
3
#justify-content: center
1
2
3
#justify-content: end
1
2
3
#justify-content: space-between
1
2
3

align-content

Aligns the WHOLE grid vertically when rows don't fill the container. Same as justify-content but for the cross axis.

#align-content: start
1
2
3
4
5
6
#align-content: center
1
2
3
4
5
6
#align-content: end
1
2
3
4
5
6
#align-content: space-between
1
2
3
4
5
6

grid-auto-flow

Controls how the auto-placement algorithm fills the grid. `dense` back-fills earlier holes when a later item is smaller.

#grid-auto-flow: row
1
2
3
4
5
6
7
#grid-auto-flow: dense
1
2
3
4
5
6
7

grid-auto-rows / grid-auto-columns

Sets the size of IMPLICIT rows (rows created by auto-placement, not defined by grid-template-rows). Useful for bento layouts with variable content.

#grid-auto-rows: 80px
1
2
3
4
5
6
#grid-auto-rows: minmax(60px, auto)
short
bit longer content that wraps
x

Item properties

These go on the grid items themselves. Override the container's alignment or make one item span multiple tracks.

grid-column

How many columns an item spans, and where it starts. `span N` is the most-used syntax.

1
2
3
4
5
#/* item 1 */ grid-column: 1 / 3
1
2
3
4
5
#/* item 1 */ grid-column: 1 / -1See real demo → CSS Featured Article Magazine Grid
1
2
3
4
5

grid-row

Same as grid-column but for rows. Combine with grid-column to make bento hero cells.

1
2
3
4
5
6
#/* item 1 */ grid-row: 1 / 3
1
2
3
4
5
6

grid-area

Names an item so grid-template-areas can reference it. Also a shorthand for grid-row-start / grid-column-start / grid-row-end / grid-column-end.

hero
small
card
#/* item 1 */ grid-area: 1 / 1 / 3 / 3
1
2
3
4
5
6

justify-self

Overrides justify-items for ONE item. Use when the container aligns siblings one way but you need one item different.

#/* item 2 */ justify-self: stretch
1
2
3
#/* item 2 */ justify-self: start
1
2
3
#/* item 2 */ justify-self: center
1
2
3
#/* item 2 */ justify-self: end
1
2
3

align-self

Overrides align-items for ONE item. Same override pattern, different axis.

#/* item 2 */ align-self: stretch
1
2
3
#/* item 2 */ align-self: start
1
2
3
#/* item 2 */ align-self: center
1
2
3
#/* item 2 */ align-self: end
1
2
3

Modern Grid (2026-ready)

Grid Level 3 + adjacent spec features that reached Baseline recently. Each row shows the browser-support level so you know whether to ship-and-forget or wrap in @supports.

subgridWidely available · 2023

Nested grids inherit the PARENT grid's tracks. Kills the cards-inside-cards inconsistent-alignment problem — titles / bodies / footers align across sibling cards even when content lengths differ.

#grid-template-rows: subgrid; grid-row: span 3
Basic
Short blurb.
$0/mo
Pro
A much longer blurb that spans more lines to prove the point.
$29/mo
Team
Medium blurb here.
$99/mo
#grid-template-columns: subgrid; grid-column: span 4
1
2
3
4
1
2
3
4

grid-template-rows: masonryLimited

Pinterest-style layout without JavaScript. Ship-behind-@supports today: Chrome 121+ and Safari 17.4+ have it; Firefox is behind a flag as of 2026-08. Fallback (a regular grid) still looks acceptable.

#@supports (grid-template-rows: masonry) { .gallery { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: masonry; gap: 8px; } }
1
2
3
4
5
6
7
8
9
#/* Fallback: grid-auto-flow: dense back-fills */ .gallery { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 40px; grid-auto-flow: dense; gap: 6px; }
1
2
3
4
5
6
7
8
9
10
11

Grid + container queriesWidely available · 2023

Grid children reshape based on THEIR OWN width, not the viewport. Essential for dashboard cards or sidebar widgets that live in variable-width containers where viewport-based media queries lie about actual available space.

#.card { container-type: inline-size } @container (min-width: 320px) { .card .body { display: grid; grid-template-columns: auto 1fr; gap: 12px; } }
@container: wide
1
side-by-side
@container: narrow
2
stacked

About this tool

Every CSS Grid property visualized on one scannable page, plus 6 ready-to-paste canonical recipes (Holy Grail, Bento, Photo Gallery, Sidebar, Auto-fit Cards, Pricing), a live playground you can drag sliders in to see the CSS update in real time, and dedicated modern-Grid sections for subgrid, Grid Level 3 masonry, and container queries with Baseline browser-support chips so you know exactly what's safe to ship. ~40 property rows across 12 sections plus 3 modern-feature sections. Every row has an anchor id you can deep-link to (e.g. #grid-template-columns-auto-fit, #subgrid-rows), a copy button that grabs the CSS declaration, and a live visual demo. Selected rows link to real production demos where the property is central. Reference chart + interactive playground — when you need to BUILD a full layout, jump to the CSS Grid Generator (linked from every section header).

?

What makes this cheat sheet different

🎯
~40 property visualizations + 6 ready-to-paste recipes
Every CSS Grid property with a live visual demo. Container properties (grid-template-columns, grid-template-rows, grid-template-areas, gap, alignment, auto-flow) + item properties (grid-column, grid-row, grid-area, self-alignment). Above the property reference: 6 canonical recipes (Holy Grail, Bento, Photo Gallery, Sidebar, Auto-fit Cards, Pricing) as complete copy-paste blocks. Every row + recipe has a Copy button.
🔗
Anchor-linked deep-linking
Share <code>/tools/css-grid-cheatsheet/#grid-template-columns-auto-fit</code> in a code review or Slack thread and the recipient lands on the exact row. Every property row + every value variant has a stable anchor id — useful for docs, PR reviews, and quick "see this row" pointers.
🌐
Links to real production demos
Where a Grid property maps cleanly to a shipped codefronts collection demo (e.g. <code>grid-template-columns: repeat(auto-fit, minmax())</code> → CSS Auto-Fit Blog Archive Grid), the row links directly to the per-demo page. See the property in a real production context in one click — not on a gallery landing you have to hunt through.
🧭
Cross-linked to the interactive generator
When you need to BUILD a specific layout (not just look up a value), the "Grid Generator" CTA at the top jumps you to the interactive builder — same palette, same visual language, so the two tools read as a family. Cheat sheet for lookup, generator for build.

How to use this reference

01
Start with a canonical recipe (fastest path)
If you know what you're building — Holy Grail, Bento, Sidebar, Photo Gallery, Pricing, Auto-fit Cards — copy the whole recipe from the top of the page. Zero synthesis needed; the recipe combines all the properties correctly.
02
Or scan by property when tweaking
The page splits into "Container properties" (parent) and "Item properties" (children). Every property has its own section with all its values, live-demoed. Skim the visuals to see what each value does.
03
Copy any declaration in one click
Every row + every recipe has a Copy button that grabs the exact CSS. Paste into your stylesheet — done.
04
Deep-link to a specific value if needed
Click the # anchor to get a URL that jumps directly to that value row. Useful for code-review comments ("this is what I mean, see #grid-column-span-2") and docs.

Modern Grid patterns worth knowing

Subgrid — align nested grids
/* Subgrid — Baseline 2023. Children align to the
   PARENT grid's tracks, not their own. Kills the "cards
   inside cards have inconsistent alignment" problem. */
.parent {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  /* Card's title, body, footer now align to parent rows. */
}
Masonry — Grid Level 3 (2026)
/* Grid Level 3 masonry — Chrome 121+, Safari 17.4+
   (behind flag in Firefox 2026). Progressive-enhance
   with @supports; falls back to a plain grid elsewhere. */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}
@supports (grid-template-rows: masonry) {
  .gallery { grid-template-rows: masonry }
}
Grid + aspect-ratio for photo tiles
/* Grid + aspect-ratio for photo/card grids that
   preserve proportions without JavaScript. */
.tile {
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.tile > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
Grid + container queries
/* Grid inside a container query — cards reshape based
   on THEIR OWN width, not viewport. Essential for
   dashboard cards that live in variable-width sidebars. */
.card { container-type: inline-size }

@container (min-width: 320px) {
  .card .body {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 12px;
  }
}

Pro tips (and the sharp edges)

01
`repeat(auto-fit, minmax(N, 1fr))` is the single most-useful Grid pattern
Responsive card grid in ONE line, no media queries. <code>auto-fit</code> collapses empty tracks (better for most cases than <code>auto-fill</code>, which preserves them). <code>minmax(240px, 1fr)</code> means "at least 240px, grow to fill". Ships everything from blog archives to product grids to team member grids in a single declaration.
02
Grid vs Flexbox — decide by axis-count
<strong>Two-axis layout</strong> (rows AND columns matter, cells align both ways) → Grid. <strong>Single-axis layout</strong> (a row of nav items, a column of stacked cards) → Flexbox. Common mistake: reaching for Grid when a horizontal navbar is really a Flexbox problem. Rule of thumb: if you're only setting one of `grid-template-rows` or `grid-template-columns`, you probably want Flexbox instead.
03
`grid-template-areas` beats column/row math for holy-grail layouts
The alternative — `.header { grid-column: 1 / -1; grid-row: 1 }` on every element — reads as line-number arithmetic. `grid-template-areas: "header header header" "nav main aside" "footer footer footer"` reads as an ASCII-art wireframe. Same output; second one survives 6 months of maintenance without a re-read. Use areas for named-region layouts, use column/row numbers for auto-generated content.
04
`min-width: 0` on grid children with overflowing content
Grid items default to `min-width: auto` which prevents shrinking below intrinsic content width. Long unbreakable strings (URLs, code, non-wrapping text) force the parent to grow beyond its column definition. Fix: add `min-width: 0` to the item so it can shrink. Same trap as flexbox has.
05
Subgrid (Baseline 2023) fixes the "cards inside cards" alignment problem
Before subgrid: nested grids didn't know about each other, so a card title in row 1 of parent-tile-A wouldn't align with a title in parent-tile-B if their content lengths differed. Subgrid lets a child grid inherit the parent's track sizing. `grid-template-rows: subgrid; grid-row: span 3` on the child = its rows align to 3 rows of the parent. Baseline 2023 (Chrome 117, Safari 16, Firefox 71) — safe everywhere except very old browsers.
?

Frequently asked questions

01

Should I use CSS Grid or Flexbox? What's the decision rule?

The rule that survives all edge cases: Grid for two-axis layouts, Flexbox for one-axis layouts. If both rows AND columns matter (dashboard cards where you set both column count AND row heights, holy-grail with header + sidebar + main + footer positioned in a 2D matrix, bento layouts where hero tile spans 2 cols × 2 rows) → Grid. If only ONE axis matters (a horizontal row of nav items, a vertical stack of cards, a button row that wraps) → Flexbox. Simpler heuristic: if you're only setting one of grid-template-columns or grid-template-rows and leaving the other axis to auto-size, you probably want Flexbox instead. The two aren't rivals — real production layouts nest them (a Grid page shell containing Flexbox nav rows). CSS-Tricks' "A Complete Guide to Grid" and the equally-famous Guide to Flexbox both agree on this. Also see our Flexbox Cheat Sheet for the Flexbox side of the decision.

02

What does `repeat(auto-fit, minmax(240px, 1fr))` actually do — and why is it the most-used Grid pattern?

It creates a responsive card grid with ZERO media queries. Break it down: repeat(N, X) creates N columns each sized X. auto-fit replaces the fixed N with "as many as fit" — the browser calculates it based on container width. minmax(240px, 1fr) means "each column is at least 240px, but grow to fill available space as 1fr". Combined result: on a 1200px container you get 4 columns (240 × 4 = 960, plus gaps), on 800px you get 3 columns, on 500px you get 2, on mobile you get 1 — all automatically, no @media queries needed. This is the single most-copied Grid pattern in 2026 production codebases because it replaces ~30 lines of media-query breakpoint math with a single declaration. auto-fit vs auto-fill: auto-fit collapses empty tracks (better for most cards — the visible tiles expand to fill); auto-fill preserves empty tracks (occasionally useful when you want a consistent column count regardless of item count, e.g. a calendar grid). 95% of the time, auto-fit is right.

03

When should I use `grid-template-areas` vs the `grid-column: 1 / -1` line-number syntax?

Use grid-template-areas when the layout has NAMED regions (header, nav, main, aside, footer) that a designer or writer would recognize by name. The ASCII-art syntax reads as a wireframe: grid-template-areas: "header header header" "nav main aside" "footer footer footer". Six months later, when you re-open the file, you understand it in one glance. Use grid-column / grid-row line numbers when items are auto-generated (a photo gallery where each tile might span 1 col or 2 cols or 3 cols based on content) or when the layout is procedural. Line numbers are arithmetic — powerful but require re-parsing every time. Best-case: use areas for the outer app-shell layout (readable at glance) + line numbers inside content grids (procedural, per-item). The two compose cleanly. Real production examples of both: grid-template-areas dashboard template for named regions; asymmetric bento for span-based bento layouts.

04

What is subgrid and when do I actually need it?

Subgrid (Baseline 2023 — Chrome 117, Safari 16, Firefox 71) lets a nested Grid inherit the PARENT grid's tracks instead of creating its own. The problem it solves: without subgrid, if you have a parent grid of 3 equal-width cards, and each card contains a nested grid (title / body / footer), the title heights in card A won't align with card B — because each nested grid sizes its own rows independently based on its content. With subgrid: .card { display: grid; grid-template-rows: subgrid; grid-row: span 3 }. Now every card's title-row, body-row, and footer-row snap to the SAME height across all cards, regardless of individual content length. Perfect vertical alignment across a card grid without JavaScript or manual height-matching. Use when: pricing tables (all "features" rows should align), team member cards (all bio-rows same height), product grids (all price-rows aligned). Baseline browser support is excellent for 2026 production; no fallback needed unless you're targeting <= 2022 browsers.

05

How do I use CSS Grid Level 3 masonry — and is it production-ready in 2026?

Grid Level 3 masonry is browser-native Pinterest-style layout without JavaScript. Syntax: grid-template-rows: masonry on the container (with grid-template-columns defining columns as usual). Browser support in August 2026: Chrome 121+ ✓, Safari 17.4+ ✓, Firefox behind a flag. Safe for production ONLY with the @supports progressive-enhancement pattern: @supports (grid-template-rows: masonry) { .gallery { grid-template-rows: masonry } }. The fallback (a regular grid without masonry) still looks acceptable — you get a rigid-rows Pinterest-lite instead of the true masonry algorithm. Alternative: grid-auto-flow: dense gives you a similar back-fill-holes effect using core Grid (universal support), though the algorithm is less sophisticated. For a real masonry gallery that works everywhere in 2026, ship the @supports masonry version with the grid-auto-flow: dense fallback baked in — see the Photo Gallery recipe at the top of this page for the pattern.

06

Does this cheat sheet work with Tailwind CSS, or only vanilla CSS?

Both — because it teaches the underlying CSS Grid properties, which Tailwind's grid utilities are 1:1 mappings of. grid = display: grid, grid-cols-3 = grid-template-columns: repeat(3, minmax(0, 1fr)), col-span-2 = grid-column: span 2 / span 2, gap-4 = gap: 1rem, place-items-center = place-items: center, etc. See the Tailwind Grid docs for the utility-to-property mapping. Note: Tailwind's named tokens (grid-cols-12, col-span-6) cover the common cases; for arbitrary values (e.g. grid-template-columns: 200px 1fr 100px) use Tailwind's arbitrary-value syntax: grid-cols-[200px_1fr_100px]. Same underlying CSS, more punctuation. For CSS-in-JS libraries (styled-components, emotion, vanilla-extract), they emit the same CSS underneath — the properties you see on this page. React / Vue / Svelte / Astro / Next.js / Nuxt / SvelteKit / Remix / Solid — all render into HTML+CSS, and Grid is a CSS property, so it applies everywhere. Framework-agnostic on purpose: learn Grid once, apply everywhere.

Search CodeFronts

Loading…