Table of Contents
What Is CSS Grid?
CSS Grid Layout is a two-dimensional layout system for the web that allows you to control both columns and rows simultaneously. Unlike Flexbox (which is primarily one-dimensional), CSS Grid gives you the power to create complex, responsive grid layouts with predictable spacing and alignment — all with clean, readable CSS.
First introduced in 2017 and now supported by over 99% of global browsers, CSS Grid has become the de facto standard for page-level layout on the modern web. By 2025, Grid has evolved with new features like subgrid, masonry support (via CSS Grid Level 3), and improved developer tooling in all major browsers.
This CSS grid layout guide will take you from absolute beginner to confident practitioner, with real-world patterns you can use immediately in your projects.
Grid vs Flexbox: When to Use What
One of the most common questions developers ask: "Should I use Grid or Flexbox?" The answer depends on the layout you need to create.
| Layout Need | Best Choice | Why |
|---|---|---|
| Page-level layout (header, sidebar, main, footer) | CSS Grid | Two-dimensional control over both rows and columns |
| Navigation bars and menus | Flexbox | One-dimensional, items flow naturally |
| Card grids (photo galleries, blog posts) | CSS Grid | Control alignment in both directions automatically |
| Centering content | Flexbox | Simpler with justify-content and align-items |
| Form layouts | CSS Grid | Label-input pairs align perfectly in 2D |
| Equal-height columns | Both | Grid does it naturally, Flexbox needs align-items: stretch |
| Content-based wrapping (like tags) | Flexbox | Items wrap naturally based on content size |
The simple rule: use Grid for two-dimensional layouts (rows AND columns), and Flexbox for one-dimensional layouts (either rows OR columns). Many modern layouts use both — Grid for the overall page structure and Flexbox for the components within each grid cell.
Grid Container Properties
To create a grid, apply display: grid to a container element. This makes all direct children grid items. Here are the essential grid container properties you need to know:
grid-template-columns and grid-template-rows
These define the column and row structure of your grid:
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
This creates a 3-column layout with a fixed sidebar (200px), a flexible main area, and another fixed sidebar (200px). The rows auto-size for header/footer content and stretch for the main content area.
The fr Unit
The fr unit distributes available space proportionally. It stands for "fraction" of the remaining space after fixed tracks are calculated:
grid-template-columns: 1fr 2fr 1fr;
/* Available space is split into 4 equal parts: 1+2+1 = 4.
Column 1 gets 1/4, column 2 gets 2/4, column 3 gets 1/4. */
repeat() Function
The repeat() function reduces repetition in grid definitions:
/* These are equivalent */
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
minmax() Function
Define minimum and maximum sizes for tracks:
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
/* Each column is at least 300px wide and grows equally to fill the container */
The auto-fill and auto-fit Keywords
These keywords work with repeat() to create truly responsive grids without media queries:
/* auto-fill creates as many columns as possible */
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
/* auto-fit is similar but collapses empty tracks to zero width */
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
The difference: auto-fill preserves the track space even when columns are empty, while auto-fit collapses empty tracks allowing your grid items to grow wider.
The gap Property
Add spacing between grid items without creating outer margins:
.grid-container {
gap: 1.5rem;
/* Shortcut for row-gap: 1.5rem; column-gap: 1.5rem; */
}
justify-content and align-content
Control the alignment of the entire grid within its container:
.grid-container {
justify-content: center; /* Horizontal alignment */
align-content: center; /* Vertical alignment */
}
Grid Item Properties
Grid items can span multiple tracks, be positioned explicitly, and aligned independently. Here are the key properties:
grid-column and grid-row
Control how many columns or rows an item spans:
.item {
grid-column: 1 / 3; /* Start at column 1, end at column 3 (spans 2 columns) */
grid-row: 1 / 2; /* Start at row 1, end at row 2 (spans 1 row) */
}
/* Using span keyword */
.item {
grid-column: 1 / span 2; /* Start at column 1, span 2 columns */
}
/* Using named lines */
.item {
grid-column: main-start / main-end;
}
align-self and justify-self
Override alignment for individual items:
.item {
align-self: center; /* Vertical alignment override */
justify-self: stretch; /* Horizontal alignment override */
}
order
Reorder grid items without changing the HTML:
.item:first-child { order: 2; }
.item:last-child { order: 1; }
/* The last child renders before the first child */
Responsive Grid Patterns
The power of CSS Grid shines in responsive design. Here are three essential responsive grid patterns you will use constantly:
Pattern 1: Auto-Fit Cards Grid
The most popular responsive grid pattern. Cards automatically wrap when the container shrinks:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
No media queries needed. When the container is 900px wide, you get 3 columns. At 650px, 2 columns. Below 330px, 1 column. The grid handles everything.
Pattern 2: Sidebar + Main Layout
A classic blog or dashboard layout with a fixed-width or min-width sidebar:
.page-layout {
display: grid;
grid-template-columns: minmax(250px, 300px) 1fr;
gap: 2rem;
}
@media (max-width: 768px) {
.page-layout {
grid-template-columns: 1fr;
}
}
Pattern 3: Holy Grail Layout
The classic header, sidebar, main content, aside, and footer layout:
.holy-grail {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
@media (max-width: 768px) {
.holy-grail {
grid-template-areas:
"header"
"sidebar"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
Named Grid Areas
Named grid areas make your CSS self-documenting. Instead of remembering which column numbers correspond to which section, you assign names and reference them directly:
.dashboard-layout {
display: grid;
grid-template-areas:
"nav nav nav"
"sidebar main widgets"
"sidebar analytics widgets"
"footer footer footer";
grid-template-columns: 240px 1fr 280px;
grid-template-rows: auto 1fr auto auto;
gap: 1.5rem;
height: 100vh;
}
.nav { grid-area: nav; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.widgets { grid-area: widgets; }
.analytics { grid-area: analytics; }
.footer { grid-area: footer; }
This approach is especially powerful in complex layouts. You can see the entire page structure at a glance from the grid-template-areas declaration. When you need to change the layout for different screen sizes, you only change the grid-template-areas string.
Subgrid in 2025
Subgrid allows nested grid items to inherit the track definitions of their parent grid. This solves one of CSS Grid's original limitations: aligning items inside nested grid containers with the outer grid's columns.
.parent-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.parent-grid > li {
display: grid;
grid-template-rows: subgrid;
/* The child inherits the parent's row tracks */
grid-row: span 2;
gap: 0;
}
Subgrid is supported in all modern browsers as of 2025 (Chrome 117+, Firefox 71+, Safari 16+). It is particularly useful for:
- Card layouts: Ensuring all card titles, descriptions, and buttons align across rows.
- Form layouts: Aligning labels and inputs across multiple form groups.
- Dashboard widgets: Synchronizing header, content, and footer regions in widget blocks.
The main limitation is that subgrid only works in one dimension at a time — you can subgrid either rows or columns, not both simultaneously (though this restriction is being addressed in CSS Grid Level 3).
Masonry and Auto-Fill Patterns
CSS Grid Level 3 introduces native masonry layout support. While it is still in development in some browsers (Chrome has an experimental flag), you can already achieve masonry-like layouts with standard CSS Grid:
.masonry {
columns: 3;
column-gap: 1.5rem;
}
.masonry > * {
break-inside: avoid;
margin-bottom: 1.5rem;
}
For a true grid-based masonry that aligns horizontally and vertically, combine multiple grid properties:
.grid-masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-auto-rows: 20px;
gap: 1rem;
}
.grid-masonry > .tall {
grid-row: span 6; /* 120px */
}
.grid-masonry > .short {
grid-row: span 3; /* 60px */
}
This approach gives you a brick-wall masonry effect where items auto-fill the grid and span varying heights based on their content.
Animating Grid Layouts
CSS Grid layouts can be animated using transitions and CSS animations, though there are some limitations in 2025.
What You Can Animate
gap— smooth transitions between gap values- Item placement with
transforminside grid cells - Grid dimensions using
grid-template-columnsandgrid-template-rowswithfrunits (Chrome supports this) opacityandtransformon grid items for enter/exit animations
What You Cannot Animate (Yet)
grid-template-areas— changing area arrangements cannot be smoothly animatedgrid-columnandgrid-rowchanges — item repositioning jumps, does not animate
.grid-container {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
transition: gap 0.3s ease, grid-template-columns 0.3s ease;
}
.grid-container.collapsed {
grid-template-columns: 60px 1fr;
gap: 0.5rem;
}
For more complex grid animations, pair CSS Grid with the transform property on individual items:
.grid-item {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.grid-item.entering {
transform: scale(0.8);
opacity: 0;
}
.grid-item.visible {
transform: scale(1);
opacity: 1;
}
Common Grid Layout Examples
Example 1: Blog Homepage
.blog-homepage {
display: grid;
grid-template-columns: 1fr 320px;
grid-template-areas:
"featured sidebar"
"recent sidebar"
"newsletter newsletter";
gap: 2rem;
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
@media (max-width: 768px) {
.blog-homepage {
grid-template-columns: 1fr;
grid-template-areas:
"featured"
"recent"
"sidebar"
"newsletter";
}
}
Example 2: Photo Gallery Grid
.gallery {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
gap: 0.5rem;
}
.gallery .featured {
grid-column: span 2;
grid-row: span 2;
}
.gallery .wide {
grid-column: span 2;
}
.gallery .tall {
grid-row: span 2;
}
Example 3: Pricing Table
.pricing-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
align-items: start;
}
.pricing-grid .popular {
transform: scale(1.05);
z-index: 1;
}
These patterns form the foundation of most web layouts you will build. For production-ready implementations, the PixelGlass UI Kit includes 5 complete templates with over 50 responsive components built with CSS Grid — from blog layouts and gallery grids to complex dashboard structures, all using the patterns covered in this CSS grid layout guide.
FAQ
What is the difference between CSS Grid and Flexbox?
CSS Grid is two-dimensional (rows and columns simultaneously), while Flexbox is one-dimensional (either rows or columns). Grid is ideal for page layouts, gallery grids, and complex alignments. Flexbox excels at components, navigation, centering, and content-driven wrapping.
Does CSS Grid replace the need for media queries?
For many patterns, yes. Using auto-fit with minmax() eliminates most media queries required for responsive card grids. However, complex layout rearrangements (like moving a sidebar below the main content) still benefit from media queries.
Can I use CSS Grid with Internet Explorer?
Internet Explorer supported an older, non-standard version of CSS Grid (IE 10 and 11). In 2025, IE has been fully retired by Microsoft. All modern browsers support the standard CSS Grid specification. Do not optimize for IE.
What is subgrid and when should I use it?
Subgrid (grid-template-rows: subgrid) makes the children of a grid item inherit the parent grid's track definitions. Use it when you need nested grid items to align with the outer grid, such as aligning content across multiple cards in a grid.
How do I create equal-height columns with CSS Grid?
By default, CSS Grid items within the same row stretch to match the tallest item. No additional CSS is needed — equal-height columns are built into Grid.
What is the auto-fill vs auto-fit difference?
auto-fill generates grid tracks even when there are no items to fill them, preserving the track space. auto-fit collapses empty tracks to zero width, allowing items to expand into the available space. Use auto-fill when you want to preserve the grid structure, and auto-fit when you want items to grow to fill gaps.
Conclusion
CSS Grid has transformed web layout from a frustrating exercise in hacks and workarounds into a powerful, declarative system. This CSS grid layout guide has covered everything from basic container properties to advanced subgrid and masonry patterns — giving you the tools to build any layout you can imagine.
The key takeaways:
- CSS Grid is your tool for two-dimensional layouts. Use it for page structure, card grids, and complex component layouts.
- Learn the core properties:
grid-template-columns,grid-template-rows,gap, and thefrunit. - Master responsive patterns with
auto-fit,auto-fill, andminmax()— they eliminate most media queries. - Named grid areas make complex layouts readable and maintainable.
- Subgrid solves alignment problems in nested layouts.
- Combine Grid with Flexbox for the most flexible, maintainable layouts.
If you want to skip the setup and start with production-ready grid layouts, the PixelGlass UI Kit includes 5 responsive templates with 50+ components — all built with modern CSS Grid and design tokens. Every grid pattern from this guide is used and ready to customize.
Related articles: Responsive Web Design Best Practices 2025 | CSS Design System Tokens Guide