Skip to main content
Settings
Color Mode
Theme Skin
Background

Appearance preferences are saved in this browser only.

Environment
Current Environment Production

Built with JEKYLL_ENV=production. Changes require deployment.

Theme & Build
Jekyll v3.10.0
Last Build Jul 13, 20:45
Page Location
Page Info
Layout article
Collection posts
Path _posts/tutorial/2025-01-23-css-grid-mastery.md
URL /posts/2025/01/23/css-grid-mastery/
Date 2025-01-23
Featured

CSS Grid Mastery: Build Any Layout You Can Imagine

CSS Grid is the most powerful layout system in CSS. This tutorial takes you from your first grid to complex, real-world layouts — and every concept comes with a live demo you can see rendered right here in the browser, sitting next to the code that produces it. Resize the window or open your browser’s grid inspector to watch each example respond.

How Grid Thinks

Flexbox lays out content in a single direction — a row or a column. Grid works in two dimensions at once: you define columns and rows, then place items into the cells they create. That makes Grid the right tool for page-level layouts, dashboards, image galleries, and any design where alignment matters both across and down.

Every demo below is real CSS Grid rendered by your browser — not a screenshot. Each one sits next to the code that produces it, so you can read the rule and see its effect in the same place.

Getting Started with Grid

Creating a Grid Container

Set display: grid on a container, declare your columns, and the children become grid items automatically.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto;
  gap: 20px;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
Live result · repeat(3, 1fr)
1
2
3
4
5
6

Six items flow into three equal columns, wrapping onto a new row automatically. The gap is the gutter you can see between every cell.

Essential Grid Properties

Defining Columns and Rows

grid-template-columns accepts fixed lengths, flexible fractions, or a mix of both. These are the patterns you will reach for most often.

/* Fixed sizes */
grid-template-columns: 200px 200px 200px;

/* Flexible sizes */
grid-template-columns: 1fr 2fr 1fr;

/* Mixed */
grid-template-columns: 200px 1fr 200px;

/* Repeat function */
grid-template-columns: repeat(4, 1fr);

/* Auto-fit for responsive grids */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

The 1fr 2fr 1fr pattern splits the row into four parts and gives the middle column two of them:

Live result · 1fr 2fr 1fr
1fr
2fr
1fr

Mixing fixed and flexible tracks pins the outer columns and lets the center absorb the rest of the width:

Live result · 72px 1fr 72px
72px
1fr
72px

The fr Unit and minmax()

The fr unit represents one fraction of the leftover space in the container, distributed after fixed tracks and gaps are subtracted. Combine it with minmax(min, max) to give a track a floor and a ceiling: minmax(250px, 1fr) never lets a column shrink below 250px but allows it to grow and fill space. This pairing is the engine behind responsive grids that need no media queries.

auto-fit vs auto-fill

Both keywords build as many columns as will fit, but they treat leftover space differently. auto-fill keeps empty “phantom” tracks, so your items stay at their minimum width. auto-fit collapses empty tracks to zero, letting the real items stretch to fill the row. Drop the same three items into each and the difference is obvious on a wide screen:

/* Items stretch to fill the row */
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));

/* Empty tracks are preserved; items stay narrow */
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
Live result · auto-fit (tracks collapse, items stretch)
1
2
3
Live result · auto-fill (empty tracks reserved)
1
2
3
↔ Resize the window on a wide screen: auto-fill leaves room for columns that have no item yet.

Grid Gap

gap sets the gutter between tracks. Use the shorthand for equal spacing, or set the row and column gutters independently.

/* Shorthand */
gap: 20px;

/* Individual */
row-gap: 20px;
column-gap: 30px;
Live result · row-gap 6px · column-gap 36px
1
2
3
4
5
6

Placing Items on the Grid

Grid Lines

Grid tracks are bounded by numbered lines, starting at 1 on the left/top. -1 is shorthand for the last line, so grid-column: 1 / -1 spans every column. Use line numbers to make an item straddle multiple tracks.

.header {
  grid-column: 1 / -1; /* Span all columns */
  grid-row: 1;
}

.sidebar {
  grid-column: 1;
  grid-row: 2 / 4; /* Span rows 2 and 3 */
}

.main {
  grid-column: 2 / -1;
  grid-row: 2;
}
Live result · spanning with line numbers
headergrid-column: 1 / -1
sidebarrow 2 / 4
maingrid-column: 2 / -1

Named Grid Areas

For layouts you can describe in words, grid-template-areas lets you draw the layout as ASCII art, then assign each item to a named region. It is the most readable way to express a page skeleton.

.container {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

.header {
  grid-area: header;
}
.sidebar {
  grid-area: sidebar;
}
.main {
  grid-area: main;
}
.footer {
  grid-area: footer;
}
Live result · grid-template-areas
header
sidebar
main

Try It: Interactive Grid Playground

Reading about tracks is one thing — feeling them snap into place is another. Click a value below to rewrite grid-template-columns on the live grid and watch the eight items reflow instantly.

Interactive · choose a column template
repeat(4, 1fr) 1fr 2fr 1fr repeat(2, 1fr) 80px 1fr 80px auto-fit minmax
1
2
3
4
5
6
7
8
grid-template-columns: repeat(4, 1fr);

Real-World Layout Examples

Card Grid (Auto-responsive)

The single most useful Grid recipe: a card grid that reflows on its own, no breakpoints required. auto-fill plus minmax decides how many cards fit per row as the container resizes.

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 24px;
  padding: 24px;
}

.card {
  background: white;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

Holy Grail Layout

The classic application shell — header, footer, a main column, and two flanking rails. Named areas make it a four-line declaration, and a single media query collapses it into a single column on small screens.

.holy-grail {
  display: grid;
  grid-template:
    "header header header" auto
    "nav    main   aside" 1fr
    "footer footer footer" auto
    / 200px 1fr 200px;
  min-height: 100vh;
}

@media (max-width: 768px) {
  .holy-grail {
    grid-template:
      "header" auto
      "nav" auto
      "main" 1fr
      "aside" auto
      "footer" auto
      / 1fr;
  }
}
Live result · resize narrow to watch it stack
header
nav
main content
aside
footer

Magazine Layout

Editorial layouts mix a large feature tile with smaller stories. Span the feature across two columns and two rows, let a secondary block run wide, and allow the rest to auto-place around them.

.magazine {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 200px);
  gap: 16px;
}

.featured {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}

.secondary {
  grid-column: 3 / 5;
}
Live result · feature + auto-placed stories
Featuredspans 2 × 2
Secondaryspans 2 cols
1
2
3
4
5
6

Advanced Techniques

Alignment

Grid gives you two axes of control. justify-* works along the row (horizontal), align-* along the column (vertical). Set defaults on the container with justify-items/align-items, then override a single item with justify-self/align-self.

.container {
  /* Align all items within their cells */
  justify-items: center; /* horizontal */
  align-items: center; /* vertical */

  /* Align the whole grid within the container */
  justify-content: center;
  align-content: center;
}

.item {
  /* Override one item */
  justify-self: end;
  align-self: start;
}
Live result · all centered, one self-aligned
center
center
end / start
center
center
center

Implicit Grid and Dense Packing

When items land outside your explicit tracks, Grid creates implicit rows to hold them — size those with grid-auto-rows. Set grid-auto-flow: dense and Grid backfills earlier gaps with later items that fit, producing a tight, masonry-like pack.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Size auto-created rows */
  grid-auto-rows: minmax(100px, auto);
  /* Backfill holes with items that fit */
  grid-auto-flow: dense;
}
Live result · mixed spans packed with dense
span 2
span row 2
3
4
span 2
6
7
8
9

Subgrid

When a grid item is itself a grid, grid-template-columns: subgrid (or subgrid for rows) lets the child reuse the parent’s track lines instead of defining its own. It is the cleanest fix for card grids where every card’s header, body, and footer must line up across the whole row regardless of content length. Subgrid is now supported across all major browsers.

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.card {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid; /* share the parent's row lines */
}

Browser DevTools

Your browser’s grid inspector turns these abstractions into something you can see:

  1. Open DevTools (F12, or Cmd+Opt+I on macOS).
  2. Select the grid container in the Elements panel.
  3. Click the grid badge next to it to toggle the overlay.
  4. Enable line numbers and area names to label every track.

Chrome and Firefox both render the overlay live, so editing grid-template-columns in the Styles panel updates the lines as you type — try it on any demo on this page.

Conclusion

CSS Grid makes complex layouts simple. Start with display: grid and a column template, lean on fr and minmax for responsive sizing, reach for named areas when a layout reads better as a picture, and finish with alignment and dense packing for the details. With the patterns above — and the live demos to experiment against — you have everything you need to build sophisticated layouts with confidence.

For the complete property reference, keep MDN’s CSS Grid Layout guide close while you practice.

Comments