CSS Grid is a two-dimensional layout system that handles both rows and columns simultaneously. While Flexbox is great for one-direction flow, Grid shines when you need precise control over a full page or component layout.
Basic Grid
Apply display: grid and define columns:
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 1rem;
}<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>This creates a 3-column grid. Items flow left-to-right, wrapping to new rows automatically. The fr unit distributes available space proportionally — three 1fr columns each get one-third.
Defining Rows and Columns
.layout {
display: grid;
grid-template-columns: 250px 1fr; /* fixed sidebar + fluid main */
grid-template-rows: auto 1fr auto; /* header + content + footer */
min-height: 100dvh;
}You can mix units freely:
| Unit | Behavior |
|---|---|
1fr | Takes a fraction of remaining space |
200px | Fixed pixel width |
auto | Sizes to content |
minmax(200px, 1fr) | At least 200px, grows up to 1fr |
The repeat() function
Instead of writing 1fr 1fr 1fr 1fr, use repeat():
.grid {
/* 4 equal columns */
grid-template-columns: repeat(4, 1fr);
/* Pattern: small, large, small, large */
grid-template-columns: repeat(2, 100px 1fr);
}Grid Template Areas
Named areas let you define layouts visually in CSS:
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100dvh;
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main { grid-area: main; }
.page-footer { grid-area: footer; }<div class="page">
<header class="page-header">Header</header>
<aside class="page-sidebar">Sidebar</aside>
<main class="page-main">Content</main>
<footer class="page-footer">Footer</footer>
</div>The grid-template-areas property maps directly to how the layout looks. Each string is a row, and each word is a column. Use . for empty cells:
grid-template-areas:
"header header"
". main"
"footer footer";Placing Items
Place items on specific grid lines using grid-column and grid-row:
.hero {
grid-column: 1 / -1; /* span all columns (1 to last line) */
}
.sidebar {
grid-column: 1 / 2; /* first column */
grid-row: 2 / 4; /* span rows 2 and 3 */
}
.featured {
grid-column: span 2; /* span 2 columns from current position */
}Line numbers start at 1. Negative numbers count from the end, so -1 is the last line.
Auto-Flow and Implicit Grids
When items overflow the explicit grid, CSS creates implicit rows or columns:
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px; /* implicit rows are 200px tall */
gap: 1rem;
}Change the flow direction with grid-auto-flow:
.horizontal {
display: grid;
grid-auto-flow: column; /* items flow into new columns */
grid-template-rows: repeat(3, 1fr); /* 3 rows defined */
grid-auto-columns: 200px; /* implicit columns are 200px */
}Responsive Grids Without Media Queries
The most powerful Grid technique is auto-fitting columns that adapt to available space:
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
}This creates as many 250px-minimum columns as fit. As the viewport shrinks, columns drop to new rows. No media queries needed.
auto-fill— creates as many tracks as fit, even if empty.auto-fit— same, but collapses empty tracks so items can stretch wider.
/* auto-fit: 2 items stretch to fill a wide container */
.stretch-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}Alignment in Grid
Grid supports the same alignment properties as Flexbox, plus a few extras:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Align all items */
justify-items: center; /* horizontal alignment within cells */
align-items: center; /* vertical alignment within cells */
/* Align the grid itself within its container */
justify-content: center;
align-content: center;
}
/* Override for a single item */
.special {
justify-self: end;
align-self: start;
}Common Grid Patterns
Dashboard layout
.dashboard {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"nav header"
"nav content";
min-height: 100dvh;
}Card grid with featured item
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
.card-grid .featured {
grid-column: span 2;
grid-row: span 2;
}Holy grail layout
.holy-grail {
display: grid;
grid-template: auto 1fr auto / 200px 1fr 200px;
grid-template-areas:
"header header header"
"left content right"
"footer footer footer";
min-height: 100dvh;
}