CSS Grid Cheat Sheet
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.
.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 }.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 {
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;
}.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. */.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 {
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.
.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).
grid-template-columns
Defines the columns of the grid. The most-used Grid property — 90% of layouts start here.
grid-template-columns: repeat(3, 1fr)grid-template-columns: repeat(auto-fit, minmax(120px, 1fr))See real demo → CSS Auto-Fit Blog Archive Gridgrid-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-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 Templategrid-template-areas:
"hero hero small"
"hero hero card"See real demo → Modern CSS Grid Bento Dashboardgap
Space between tracks. No outer margin, no :first/:last-child gymnastics, no negative-margin hacks.
justify-items
Aligns items horizontally within their cells. Default is stretch (each item fills its cell).
align-items
Aligns items vertically within their cells. Default is stretch.
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.
align-content
Aligns the WHOLE grid vertically when rows don't fill the container. Same as justify-content but for the cross axis.
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-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.
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.
grid-row
Same as grid-column but for rows. Combine with grid-column to make bento hero cells.
/* item 1 */ grid-row: 1 / 3grid-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.
/* item 1 */ grid-area: 1 / 1 / 3 / 3justify-self
Overrides justify-items for ONE item. Use when the container aligns siblings one way but you need one item different.
align-self
Overrides align-items for ONE item. Same override pattern, different axis.
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: 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;
}
}/* 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;
}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;
}
}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
How to use this reference
Modern Grid patterns worth knowing
/* 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. */
}/* 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/card grids that
preserve proportions without JavaScript. */
.tile {
aspect-ratio: 4 / 3;
overflow: hidden;
}
.tile > img {
width: 100%;
height: 100%;
object-fit: cover;
}/* 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)
Frequently asked questions
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.
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.
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.
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.
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.
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.