CSS Grid Layout — How to Build Two-Dimensional Layouts
CSS Grid creates two-dimensional layouts with explicit rows and columns. Here's how grid-template-columns, grid-area, auto-fit, and minmax work with practical patterns.
CSS Grid is the most powerful layout system available in CSS. Unlike Flexbox (which is one-dimensional), Grid works in both rows and columns simultaneously. It replaced the floats, tables, and JavaScript-calculated layouts that developers used before 2017.
Use the CSS Grid Generator to build grid layouts visually and copy the generated CSS.
Activating CSS Grid
.container {
display: grid;
}
Any element with display: grid is a grid container. Its direct children become grid items. Grid doesn’t do anything visible until you define columns and rows.
grid-template-columns
Defines the number and size of columns in the grid:
.container {
display: grid;
/* Three equal columns: */
grid-template-columns: 1fr 1fr 1fr;
/* Shorthand with repeat(): */
grid-template-columns: repeat(3, 1fr);
/* Mixed sizes: */
grid-template-columns: 200px 1fr 1fr; /* Fixed sidebar + two flexible columns */
grid-template-columns: 1fr 2fr 1fr; /* Center column twice as wide */
/* Responsive with auto-fit: */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
The fr unit
fr (fraction) represents a fraction of the available space in the grid container — after fixed-width columns have been allocated.
/* Container width: 900px, no gap */
grid-template-columns: 200px 1fr 2fr;
/* 200px sidebar → 700px remaining → 1fr = 233px, 2fr = 467px */
repeat()
repeat(count, size) creates multiple identical columns without repeating yourself:
repeat(4, 1fr) /* Same as: 1fr 1fr 1fr 1fr */
repeat(3, 200px 1fr) /* Same as: 200px 1fr 200px 1fr 200px 1fr */
repeat(auto-fit, minmax(250px, 1fr)) /* Responsive — covered below */
grid-template-rows
Same syntax as grid-template-columns, for rows:
.container {
display: grid;
grid-template-rows: auto 1fr auto; /* Header: content height, main: flexible, footer: content height */
}
auto means the row height is determined by the tallest item in that row.
gap
Spacing between rows and columns:
.container {
gap: 24px; /* Same gap for rows and columns */
gap: 24px 16px; /* row-gap: 24px, column-gap: 16px */
row-gap: 24px;
column-gap: 16px;
}
Placing items: grid-column and grid-row
By default, items fill grid cells left-to-right, top-to-bottom. You can place items explicitly using line numbers.
Grid line numbers start at 1. A 3-column grid has column lines 1, 2, 3, 4.
.item {
grid-column: 1 / 3; /* Spans from column line 1 to line 3 (2 columns wide) */
grid-row: 1 / 2; /* Spans row line 1 to 2 (1 row tall) */
/* Shorthand: */
grid-column: 1 / span 2; /* Start at line 1, span 2 columns */
grid-column: 2 / -1; /* Start at line 2, end at last line */
grid-column: 1 / -1; /* Full width (all columns) */
}
Named grid areas
For complex layouts, naming grid areas is more readable than line numbers:
.container {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
The grid-template-areas value is a visual map of your layout. Each quoted string is a row. Repeated names span that area. . is an empty cell.
The responsive grid: auto-fit + minmax
This pattern is the most powerful responsive grid technique:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 24px;
}
What it does:
auto-fit: creates as many columns as fit, without creating empty columnsminmax(250px, 1fr): each column is at least 250px, at most 1fr of available space
Behavior at different viewport widths (assuming 24px gap and padding):
- 1200px container → fits 4 columns of 280px each
- 800px container → fits 3 columns of 250px each
- 500px container → fits 2 columns of 228px each
- 280px container → 1 column at full width
Zero media queries needed for this responsive behavior. The grid automatically reflows.
auto-fit vs auto-fill
/* auto-fit: collapses empty columns */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* auto-fill: keeps empty columns (placeholder columns remain) */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
The difference matters only when there are fewer items than the grid can fit. With auto-fit, items stretch to fill the remaining space. With auto-fill, empty columns remain, and items don’t stretch past their minmax maximum.
For most content grids (cards, products, blog posts), auto-fit is what you want.
Alignment in Grid
Aligning the grid tracks
.container {
/* Align columns (horizontal): */
justify-content: start | end | center | stretch | space-between | space-around | space-evenly;
/* Align rows (vertical): */
align-content: start | end | center | stretch | space-between | space-around | space-evenly;
}
Aligning items within their cells
.container {
/* Default: items fill their cells */
justify-items: start | end | center | stretch; /* horizontal within cell */
align-items: start | end | center | stretch; /* vertical within cell */
}
/* Override for individual items: */
.item {
justify-self: center;
align-self: end;
}
Centering in a grid cell
.container {
display: grid;
place-items: center; /* Shorthand for align-items + justify-items */
}
place-items: center is the most concise way to center content within each grid cell.
Grid vs Flexbox decision guide
| Use Grid when | Use Flexbox when |
|---|---|
| Two-dimensional layout (rows + columns) | One-dimensional layout (row OR column) |
| You define the layout, content fills in | Content defines the layout dimensions |
| Named areas and explicit placement | Content flow with wrapping |
| Page-level structure | Component-level structure |
| Newspaper/magazine-style layouts | Navigation bars, button groups, card rows |
They work together: use Grid for the overall page layout, Flexbox for the internal layout of components within grid areas.
Common Grid patterns
12-column grid system
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 24px;
}
/* Bootstrap-like column spans: */
.col-4 { grid-column: span 4; }
.col-6 { grid-column: span 6; }
.col-12 { grid-column: span 12; }
Holy grail layout
body {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
min-height: 100vh;
}
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }
/* Responsive: collapse to single column */
@media (max-width: 768px) {
body {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"aside"
"footer";
}
}
Masonry-like layout
CSS Grid doesn’t yet support true masonry (where items fill in variable-height cells to minimize gaps). A near-masonry effect with fixed row heights:
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-auto-rows: 8px; /* Small row unit */
gap: 16px 16px;
}
.card-short { grid-row: span 20; } /* 160px tall */
.card-medium { grid-row: span 30; } /* 240px tall */
.card-tall { grid-row: span 45; } /* 360px tall */
True CSS masonry (masonry value for grid-template-rows) is in the CSS specification but not yet broadly supported in browsers as of 2026.
Using the CSS Grid Generator
The CSS Grid Generator lets you:
- Set the number of columns and rows visually
- Drag to merge cells and create named areas
- Adjust gap, column sizes, and alignment
- Copy the complete CSS output
Useful for prototyping layouts before implementing in code, and for learning how different properties interact visually.
Related tools
- CSS Grid Generator — build CSS grid layouts visually
- Flexbox Generator — build Flexbox layouts
- Box Shadow Generator — generate box-shadow CSS values
Related posts
- CSS Grid Template Areas — Named Grid Areas Explained — CSS grid-template-areas lets you name regions of your layout and assign elements…
- CSS Grid Auto Placement — How grid-auto-flow Works — CSS grid auto-placement automatically positions items in the grid without explic…
- CSS Grid Browser Support — What Works Where in 2025 — CSS Grid has near-universal browser support as of 2025. Here's what's supported …
- CSS Flexbox — Complete Guide to flex-direction, justify-content, and align-items — Flexbox aligns items in one dimension — a row or a column. Here's how flex-direc…
Related tool
Visual CSS Grid layout builder. Configure columns, rows, gaps, and named areas. Live preview with copyable CSS output.
Written by Mian Ali Khalid. Part of the Frontend & Design pillar.