CSS Grid Layout is the most powerful layout system available in CSS. It’s a 2-dimensional system, meaning it can handle both columns and rows, unlike flexbox which is largely a 1-dimensional system. Working with CSS Grid takes a bit of getting used to, but once you understand it, you’ll never want to go back.
What is CSS Grid?
CSS Grid Layout excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer, between parts of a control built from HTML primitives.
Like tables, grid layout enables an author to align elements into columns and rows. However, many more layouts are either possible or easier with CSS grid than they were with tables.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto;
gap: 20px;
}
Grid Container vs Grid Items
When you apply display: grid
to an element, it becomes a grid container, and its direct children automatically become grid items.
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
</div>
.grid-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 100px);
gap: 10px;
}
Defining Grid Tracks
Grid Template Columns
.grid {
/* Fixed sizes */
grid-template-columns: 100px 200px 100px;
/* Flexible sizes */
grid-template-columns: 1fr 2fr 1fr;
/* Mixed */
grid-template-columns: 200px 1fr 100px;
/* Repeat notation */
grid-template-columns: repeat(3, 1fr);
/* Auto-fit and auto-fill */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
Grid Template Rows
.grid {
grid-template-rows: 50px auto 50px;
grid-template-rows: repeat(3, minmax(100px, auto));
}
Grid Areas and Template Areas
One of the most powerful features of CSS Grid is the ability to name grid areas and place items using those names.
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: 60px 1fr 60px;
gap: 20px;
}
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
Positioning Grid Items
Line-based Placement
.item {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
/* Shorthand */
grid-column: 1 / 3;
grid-row: 2 / 4;
/* Even shorter */
grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
}
Span Keyword
.item {
grid-column: 1 / span 2; /* Start at line 1, span 2 columns */
grid-row: 2 / span 3; /* Start at line 2, span 3 rows */
}
Alignment and Justification
Container-level Alignment
.grid-container {
/* Align the entire grid within the container */
justify-content: center; /* start | end | center | stretch | space-around | space-between | space-evenly */
align-content: center; /* start | end | center | stretch | space-around | space-between | space-evenly */
/* Set default alignment for all items */
justify-items: center; /* start | end | center | stretch */
align-items: center; /* start | end | center | stretch */
}
Item-level Alignment
.grid-item {
justify-self: center; /* start | end | center | stretch */
align-self: center; /* start | end | center | stretch */
}
Responsive Grid Patterns
Auto-Fit vs Auto-Fill
/* Auto-fit: empty tracks collapse */
.grid-auto-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* Auto-fill: empty tracks remain */
.grid-auto-fill {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
Responsive Card Layout
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
.card {
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
Advanced Grid Techniques
Overlapping Elements
.overlay-grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
}
.background {
grid-area: 1 / 1 / 2 / 2;
background: url("background.jpg");
}
.content {
grid-area: 1 / 1 / 2 / 2;
z-index: 1;
align-self: center;
justify-self: center;
}
Subgrid (Future Feature)
.parent-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.child-grid {
display: grid;
grid-template-columns: subgrid; /* Inherits parent's column tracks */
}
Real-World Examples
Holy Grail Layout
.holy-grail {
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;
}
@media (max-width: 768px) {
.holy-grail {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
Masonry-like Layout
.masonry {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 10px;
gap: 10px;
}
.masonry-item {
grid-row-end: span var(--rows, 20);
}
Magazine Layout
.magazine {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 200px);
gap: 20px;
}
.featured {
grid-area: 1 / 1 / 3 / 4;
}
.article-1 {
grid-area: 1 / 4 / 2 / 7;
}
.article-2 {
grid-area: 2 / 4 / 3 / 7;
}
.article-3 {
grid-area: 3 / 1 / 5 / 3;
}
.article-4 {
grid-area: 3 / 3 / 5 / 5;
}
.article-5 {
grid-area: 3 / 5 / 5 / 7;
}
Browser Support and Fallbacks
CSS Grid has excellent browser support, but here’s how to provide fallbacks:
.grid-container {
/* Fallback for older browsers */
display: flex;
flex-wrap: wrap;
/* Grid for modern browsers */
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* Feature query for additional grid styles */
@supports (display: grid) {
.grid-container {
/* Grid-specific styles */
}
}
Common Pitfalls and Solutions
1. Forgetting Grid Container
/* Won't work - children need a grid container */
.item {
grid-column: 1 / 3;
}
/* Correct */
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.item {
grid-column: 1 / 3;
}
2. Implicit vs Explicit Grid
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* Explicit */
grid-auto-rows: 100px; /* For implicit rows */
}
3. Sizing Issues
/* Problem: grid items might overflow */
.grid {
grid-template-columns: 200px 200px 200px;
}
/* Solution: use fr units or minmax */
.grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
Tools and Resources
- Firefox Grid Inspector: Best tool for visualizing grid layouts
- Chrome DevTools: Grid overlay and debugging features
- CSS Grid Generator: Online tools for creating grid layouts
- Grid by Example: Comprehensive examples and patterns
Conclusion
CSS Grid is a game-changer for web layouts. It provides precise control over both rows and columns, making complex layouts simple and maintainable. While there’s a learning curve, the investment pays off quickly.
Start with simple layouts and gradually incorporate more advanced features. Remember that Grid works beautifully alongside Flexbox - use Grid for 2D layouts and Flexbox for 1D component layouts.
The future of CSS layouts is here, and it’s incredibly powerful. Master CSS Grid, and you’ll wonder how you ever built layouts without it.