CSS Grid & Flexbox: Modern Layout Guide
Introduction
CSS Grid and Flexbox are the two most powerful layout systems in modern CSS. Understanding when and how to use each is essential for creating responsive, maintainable layouts. This guide covers both technologies with practical examples.
1. Flexbox Fundamentals
Flexbox is designed for one-dimensional layouts - either row or column.
Basic Flex Container
.container {
display: flex;
flex-direction: row; /* or column */
justify-content: space-between; /* main axis */
align-items: center; /* cross axis */
gap: 1rem;
}
Common Flexbox Patterns
/* Center content perfectly */
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Navigation bar */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
/* Card with footer at bottom */
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-content {
flex: 1; /* Takes remaining space */
}
.card-footer {
margin-top: auto;
}
Flex Item Properties
/* Grow, shrink, basis */
.item {
flex: 1; /* shorthand for flex: 1 1 0 */
/* flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
}
.sidebar {
flex: 0 0 250px; /* Don't grow or shrink, fixed 250px */
}
.main-content {
flex: 1; /* Take remaining space */
}
/* Order control */
.item-first {
order: -1;
}
.item-last {
order: 1;
}
2. CSS Grid Fundamentals
Grid is designed for two-dimensional layouts with rows and columns.
Basic Grid Container
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 2rem;
}
/* Named grid areas */
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 250px 1fr 1fr;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Responsive Grid Patterns
/* Auto-fit responsive grid */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
/* Auto-fill vs auto-fit */
.auto-fill {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* Creates as many columns as fit, including empty */
}
.auto-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* Expands columns to fill space */
}
/* Holy Grail Layout */
.holy-grail {
display: grid;
grid-template-areas:
"header header header"
"left content right"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
Grid Item Placement
/* Span multiple columns/rows */
.featured {
grid-column: span 2;
grid-row: span 2;
}
/* Specific placement */
.item {
grid-column: 1 / 3; /* Start at 1, end before 3 */
grid-row: 2 / 4;
}
/* Shorthand */
.item {
grid-area: 2 / 1 / 4 / 3;
/* row-start / column-start / row-end / column-end */
}
3. When to Use Each
Use Flexbox for:
- Navigation bars and menus
- Single-row or single-column layouts
- Centering content
- Distributing space between items
- Component-level layouts (cards, forms)
Use Grid for:
- Page-level layouts (header, sidebar, content)
- Image galleries and portfolios
- Complex two-dimensional layouts
- Magazine-style layouts
- Dashboard layouts
4. Combining Grid and Flexbox
/* Grid for page layout */
.page {
display: grid;
grid-template-columns: 250px 1fr;
gap: 2rem;
}
/* Flexbox for navigation */
.sidebar nav {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Grid for card layout */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* Flexbox within each card */
.card {
display: flex;
flex-direction: column;
padding: 1.5rem;
}
.card-actions {
display: flex;
gap: 1rem;
margin-top: auto;
}
5. Advanced Techniques
Subgrid
.parent-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.child-grid {
display: grid;
grid-template-columns: subgrid;
/* Inherits parent columns */
}
Grid with minmax()
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 2rem;
}
Flexbox Gap Support
.flex-container {
display: flex;
gap: 1rem 2rem; /* row-gap column-gap */
flex-wrap: wrap;
}
6. Responsive Examples
Responsive Dashboard
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
padding: 1.5rem;
}
.widget {
background: white;
padding: 1.5rem;
border-radius: 8px;
}
.widget.large {
grid-column: span 2;
}
@media (max-width: 768px) {
.widget.large {
grid-column: span 1;
}
}
Responsive Navigation
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
gap: 2rem;
}
.nav-links {
display: flex;
gap: 2rem;
}
@media (max-width: 768px) {
.navbar {
flex-direction: column;
align-items: stretch;
}
.nav-links {
flex-direction: column;
gap: 1rem;
}
}
7. Common Patterns
Sticky Footer
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
footer {
margin-top: auto;
}
Equal Height Columns
.columns {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
/* Or with Flexbox */
.flex-columns {
display: flex;
gap: 2rem;
}
.column {
flex: 1;
}
Masonry-like Layout
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 10px;
gap: 1rem;
}
.masonry-item {
grid-row-end: span var(--row-span);
}
- Use Grid for macro layouts, Flexbox for micro layouts
- Prefer
gapover margins for spacing - Use
auto-fitorauto-fillfor responsive grids - Leverage
frunits for flexible sizing - Test layouts at multiple screen sizes
- Use CSS custom properties for dynamic values
- Consider accessibility with logical properties
Conclusion
CSS Grid and Flexbox are complementary technologies. Grid excels at two-dimensional layouts while Flexbox is perfect for one-dimensional arrangements. By mastering both and understanding when to use each, you can create responsive, maintainable layouts for any design requirement.
Practice combining these technologies - use Grid for your page structure and Flexbox for component-level layouts to get the best of both worlds.