CSS Grid Demystified

Master CSS Grid from zero to expert — grid basics, template columns & rows, gap, named areas, item placement & spanning, alignment, auto-flow, responsive patterns, real-world layouts, and a full interactive playground.

By Forhad40 min readIntermediateInteractive Demo
CSS Grid Demystified

The Big Picture — What is CSS Grid?

CSS Grid is the most powerful layout system in CSS. Unlike Flexbox which works in one dimension (row OR column), Grid works in two dimensions simultaneously — giving you precise control over both rows and columns at the same time. It lets you define a grid structure and place items into it with pixel-perfect precision.

Grid vs Flexbox — When to Use Which?

Grid and Flexbox are complementary. Use Grid for 2D layouts, Flexbox for 1D alignment.

📐 CSS Grid — 2D

1
2
3
4
5
6

Controls rows AND columns

↔️ Flexbox — 1D

1
2
3
4

Controls ONE axis at a time

FeatureCSS GridFlexbox
Dimensions2D — rows AND columns simultaneously1D — either row OR column
Layout approachLayout-first (define grid, place items)Content-first (items determine layout)
AlignmentBoth axes independentlyMain axis + cross axis
OverlapItems can overlap (z-index)Items cannot overlap
GapNative gap propertyNative gap property (newer)
Best forPage layouts, dashboards, card gridsNavbars, toolbars, inline content

Grid Terminology

Click each term to see it highlighted on the grid.

📦Grid Container

The element with display: grid. It establishes the grid formatting context for its children.

display: grid;

Visual Grid Anatomy — 3×2 Grid

↓ 1
↓ 2
↓ 3
↓ 4
1 →2 →3 →
Header
Nav
Main
Sidebar
Footer
Ads
↕↔ = Grid Lines (numbered)--- = Grid Container (dashed border)Colored boxes = Grid Items in Cells

🔑 Key Takeaway: CSS Grid is a 2D layout system. The container defines the grid structure (tracks, lines, areas), and items are placed into cells either automatically or with explicit coordinates.

grid-template-columns

The grid-template-columnsproperty defines how many columns your grid has and how wide each one is. This is where you'll spend most of your time — mastering the fr unit, repeat(), minmax(), and the difference between auto-fill and auto-fit.

Grid Sizing Units

The building blocks for defining column and row sizes.

frFraction

Distributes remaining space. 1fr 2fr = first gets 1/3, second gets 2/3.

pxPixels

Fixed size. Doesn't grow or shrink. Use for sidebars or fixed columns.

%Percentage

Percentage of the container width. Doesn't account for gaps.

autoAuto

Sizes to content. Shrinks to fit, grows if space available.

minmax()Min-Max

Sets a min and max size. minmax(100px, 1fr) = at least 100px, up to 1fr.

fit-content()Fit Content

Like auto but capped at the given size. fit-content(200px) won't exceed 200px.

grid-template-columns — Interactive

Select a preset or type your own column definition.

Items:6

Three columns of equal width. Each gets 1 fraction of available space.

1
2
3
4
5
6
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
}

auto-fill vs auto-fit — The Key Difference

auto-fill: keeps empty tracks

1
2

Empty columns exist but items don't stretch into them

auto-fit: collapses empty tracks

1
2

Empty columns collapse — items stretch to fill the row

🔑 Key Takeaway: grid-template-columns defines your column structure. Use fr for flexible proportions, px for fixed sizes, minmax() for responsive ranges, and auto-fill/auto-fit for dynamic column counts that adapt to container width.

grid-template-rows

Rows work just like columns but on the vertical axis. The key difference: fr units for rows only work when the container has an explicit height. Without it, rows default to auto (content-sized). Understanding explicit vs implicit rows is critical.

grid-template-rows — Interactive

Rows work the same as columns — but vertically. The key difference: fr units for rows require the container to have an explicit height.

Height:400px

Rows size to their content. Most common default behavior.

Header
Nav
Search
Content
Sidebar
Ads
Footer
Links
Copyright
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto auto auto;
  gap: 8px;
  height: 400px;
}

Explicit vs Implicit Rows

Explicit Rows

Defined by grid-template-rows. You control their exact size.

Implicit Rows

Created automatically when items overflow the explicit grid. Sized by grid-auto-rows (default: auto).

/* Size implicit (overflow) rows */
.container {
  grid-template-rows: 100px 100px;  /* 2 explicit rows */
  grid-auto-rows: 60px;             /* all extra rows = 60px */
}

🔑 Key Takeaway: grid-template-rows defines explicit row heights. Use auto for content-sized rows, px for fixed heights, and fr for proportional distribution (requires explicit container height). Use grid-auto-rows to size implicit overflow rows.

gap — Spacing Between Tracks

The gap property (formerly grid-gap) adds gutters between grid tracks. Unlike margins, gap only applies between items — never on the outer edges. You can set row-gap and column-gap independently for asymmetric spacing.

gap, row-gap, column-gap

Gap adds spacing between grid tracks (not around the outer edges). It replaced the older grid-gap property.

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

gap vs margin — Why Gap Is Better

✅ gap

  • • Only between items (no outer spacing)
  • • Works with grid AND flexbox
  • • No collapsing margin issues
  • • One property controls all gutters

❌ margin

  • • Adds spacing on ALL sides (extra on edges)
  • • Need negative margin hacks to fix
  • • Margins collapse between items
  • • Each item needs its own margin

🔑 Key Takeaway: The gap property adds gutters between grid tracks without affecting the outer edges. Use the shorthand gap: row col or set row-gap and column-gap independently. Always prefer gap over margins for grid spacing.

grid-template-areas — Named Layouts

Grid areas let you define layouts visually in your CSS. Each string represents a row, each word a column. Name your regions (header, sidebar, main, footer) and assign items to them with grid-area. It's the most readable way to create complex page layouts.

grid-template-areas — Named Layouts

Define layouts visually using named areas — the most readable way to create complex grids. Each string is a row, each word is a column.

Header
Nav
Main Content
Aside
Footer

Area Map (each string = one row)

grid-template-areas:
  "header header header"
  "nav    main   aside"
  "footer footer footer"
.container {
  display: grid;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 200px 1fr 200px;
  gap: 8px;
}

.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

💡 Empty Cells: Use a dot (.)

Use . to leave a cell empty in your area template:

grid-template-areas:
  "header header header"
  ".      main   ."
  "footer footer footer";

🔑 Key Takeaway: grid-template-areas lets you design layouts visually in your CSS. Name each region, then assign items with grid-area. It's the most readable way to create complex page layouts and makes responsive redesigns trivial.

Item Placement & Spanning

By default, grid items fill cells left-to-right, top-to-bottom. But you can place any item anywhere using grid-column and grid-row with line numbers or the span keyword. Negative line numbers count from the end — grid-column: 1 / -1 spans the entire row.

Item Placement & Spanning

Control exactly where items go using grid-column, grid-row, span, and line numbers.

Place items using grid line numbers. A 3-column grid has lines 1, 2, 3, 4. Negative numbers count from the end.

col 1
col 2
col 3
col 4
A
B
C
D
E
/* Item A */
.item-A { grid-column: 1 / 3; grid-row: 1; }
/* Item B */
.item-B { grid-column: 3; grid-row: 1 / 3; }
/* Item C */
.item-C { grid-column: 1; grid-row: 2; }
/* Item D */
.item-D { grid-column: 2; grid-row: 2; }
/* Item E */
.item-E { grid-column: 1 / -1; grid-row: 3; }

Click any item above to highlight it

Placement Property Cheat Sheet

grid-column: 1 / 3Start at column line 1, end at line 3 (spans 2 columns)
grid-column: span 2Span 2 columns from current position
grid-column: 1 / -1Span the entire row (line 1 to last line)
grid-row: 2 / span 3Start at row line 2, span 3 rows
grid-area: 2 / 1 / 4 / 3Shorthand: row-start / col-start / row-end / col-end

🔑 Key Takeaway: Grid items can be placed anywhere on the grid using line numbers (grid-column: 1 / 3), span counts (grid-column: span 2), or named areas. Negative line numbers count from the end — grid-column: 1 / -1 spans the entire row.

Alignment & Justification

Grid has 6 alignment properties: justify-items and align-items position items within their cells, justify-content and align-content position the grid within its container, and justify-self / align-self override alignment for individual items.

Grid Alignment — 6 Properties

Grid has 6 alignment properties: 2 for items-in-cells, 2 for grid-in-container, 2 for individual overrides.

justify-items
All items within their cell(Inline (horizontal))
align-items
All items within their cell(Block (vertical))
justify-content
The entire grid within the container(Inline (horizontal))
align-content
The entire grid within the container(Block (vertical))
justify-self
A single item within its cell(Inline (horizontal))
align-self
A single item within its cell(Block (vertical))

Interactive Alignment Demo

justify-items (horizontal)

align-items (vertical)

1
2
3
4
5
6
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  justify-items: stretch;
  align-items: stretch;
}

Shorthand Properties

place-items: centeralign-items: center; justify-items: center;
place-content: centeralign-content: center; justify-content: center;
place-self: end centeralign-self: end; justify-self: center;

🔑 Key Takeaway: justify-* controls the inline (horizontal) axis, align-* controls the block (vertical) axis. *-items positions items within their cells, *-content positions the entire grid within its container. place-* is the shorthand for both.

grid-auto-flow — Automatic Placement

When you don't explicitly position items, the auto-placement algorithm decides where they go. grid-auto-flowcontrols whether items fill by row or by column, and whether the "dense" packing algorithm should backfill gaps left by larger items.

grid-auto-flow — Automatic Placement

Controls how the auto-placement algorithm fills items into the grid when you don't explicitly position them.

Items fill each row left-to-right, then wrap to the next row. Most common.

A (2 cols)
B
C (2 rows)
D
E (2 cols)
F
G
H

Notice how "dense" fills the gap left by wide/tall items, while non-dense leaves holes.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 60px;
  grid-auto-flow: row;
  gap: 6px;
}

.item-a { grid-column: span 2; }
.item-c { grid-row: span 2; }
.item-e { grid-column: span 2; }

The Implicit Grid

When items overflow the explicit grid (defined by grid-template-*), the browser creates implicit tracks. Control their size with:

grid-auto-rows: 60pxAll implicit rows are 60px tall
grid-auto-rows: minmax(60px, auto)At least 60px, grows with content
grid-auto-columns: 200pxAll implicit columns are 200px wide

🔑 Key Takeaway: grid-auto-flow controls how items are placed automatically. "row" fills left-to-right, "column" fills top-to-bottom. Add "dense" to backfill gaps — useful for card grids and masonry layouts. Use grid-auto-rows/columns to size implicit tracks.

Responsive Grid Patterns

CSS Grid can create fully responsive layouts without a single media query. The magic formula: repeat(auto-fit, minmax(200px, 1fr))— this creates as many columns as fit, each at least 200px wide, stretching to fill available space. It's one line of CSS that replaces dozens of breakpoint rules.

Responsive Grid Patterns

CSS Grid can create responsive layouts without a single media query. The key: auto-fit/auto-fill + minmax().

The gold standard for responsive grids. No media queries needed. Items are at least 150px wide and stretch to fill remaining space. Columns adjust automatically to container width.

Items:8
Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
Card 7
Card 8

↔ Resize your browser window to see the grid adapt

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

Common Breakpoint Strategy

< 640px1 columngrid-template-columns: 1fr;
640px – 1023px2 columnsgrid-template-columns: repeat(2, 1fr);
1024px – 1279px3 columnsgrid-template-columns: repeat(3, 1fr);
≥ 1280px4 columnsgrid-template-columns: repeat(4, 1fr);

🔑 Key Takeaway: repeat(auto-fit, minmax(200px, 1fr)) is the single most useful CSS Grid pattern. It creates a fully responsive grid that adapts to any container width — no media queries, no JavaScript, just one line of CSS.

Real-World Layouts

These are the 5 layout patterns you'll use most often: the Holy Grail (header + sidebar + content + sidebar + footer), responsive card grids, dashboard layouts, magazine-style featured content, and the simplest centering technique in all of CSS.

Real-World Grid Layouts

Common layout patterns you'll use daily. Click each to see the live preview and CSS.

The classic web layout: header, footer, main content flanked by two sidebars. Grid makes this trivial with named areas.

Header
Nav
Main
Aside
Footer
.layout {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "nav     main    aside"
    "footer  footer  footer";
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  gap: 8px;
}

🔑 Key Takeaway: CSS Grid excels at page-level layouts. The Holy Grail layout is 6 lines of CSS. Card grids are 3 lines. Perfect centering is 2 lines. Master these 5 patterns and you can build any layout.

Grid Playground

Experiment freely with every grid property. Adjust columns, rows, gap, alignment, and item count — or type custom template values. The generated CSS updates in real-time and is ready to copy into your project.

Full Grid Playground

Experiment freely — adjust every grid property and see the result instantly.

Columns (3)
Rows (3)
Gap (10px)
Cells (6)
justify-items
align-items
Custom columns (overrides slider)
Custom rows (overrides slider)
1
2
3
4
5
6
Generated CSS
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, minmax(60px, 1fr));
  gap: 10px;
  justify-items: stretch;
  align-items: stretch;
}

🔑 Key Takeaway: CSS Grid gives you complete 2D control. Define columns and rows, set gap spacing, align items within cells, and the browser handles all the math. Copy the generated CSS into your project and customize from there.