CSS Grid vs Flexbox: When to Use Each
A comprehensive comparison of CSS Grid and Flexbox, with practical examples and use cases.
CSS Grid vs Flexbox: When to Use Each
CSS Grid and Flexbox are two powerful layout systems in CSS, each with their own strengths and use cases. Understanding when to use each can significantly improve your layout skills and create more maintainable CSS.
Understanding the Differences
Flexbox (One-Dimensional)
- Designed for one-dimensional layouts (row OR column)
- Great for distributing space along a single axis
- Perfect for navigation bars, form layouts, and component alignment
CSS Grid (Two-Dimensional)
- Designed for two-dimensional layouts (rows AND columns)
- Excellent for page layouts and complex arrangements
- Perfect for card grids, dashboard layouts, and overall page structure
Flexbox Use Cases
1. Navigation Bars
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background-color: #333;
color: white;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-links li {
cursor: pointer;
}
.nav-links li:hover {
color: #ffd700;
}
<nav class="navbar">
<div class="logo">Brand</div>
<ul class="nav-links">
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
2. Form Layouts
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 1rem;
}
.form-row {
display: flex;
gap: 1rem;
}
.form-row .form-group {
flex: 1;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 1rem;
margin-top: 2rem;
}
<form>
<div class="form-row">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" id="firstName" />
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" id="lastName" />
</div>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" />
</div>
<div class="form-actions">
<button type="button">Cancel</button>
<button type="submit">Submit</button>
</div>
</form>
3. Card Components
.card {
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
max-width: 300px;
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-content {
display: flex;
flex-direction: column;
padding: 1rem;
flex: 1;
}
.card-title {
margin: 0 0 0.5rem 0;
font-size: 1.25rem;
}
.card-description {
margin: 0 0 1rem 0;
color: #666;
flex: 1;
}
.card-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
CSS Grid Use Cases
1. Page Layout
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header {
grid-area: header;
background-color: #333;
color: white;
padding: 1rem;
}
.sidebar {
grid-area: sidebar;
background-color: #f5f5f5;
padding: 1rem;
}
.main {
grid-area: main;
padding: 2rem;
}
.footer {
grid-area: footer;
background-color: #333;
color: white;
padding: 1rem;
text-align: center;
}
<div class="page-layout">
<header class="header">Header</header>
<aside class="sidebar">Sidebar</aside>
<main class="main">Main Content</main>
<footer class="footer">Footer</footer>
</div>
2. Card Grid
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
display: flex;
flex-direction: column;
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 4px;
margin-bottom: 1rem;
}
.card-content {
flex: 1;
display: flex;
flex-direction: column;
}
.card-title {
margin: 0 0 0.5rem 0;
font-size: 1.25rem;
}
.card-description {
margin: 0 0 1rem 0;
color: #666;
flex: 1;
}
.card-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
3. Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto 1fr;
gap: 1rem;
padding: 1rem;
height: 100vh;
}
.stat-card {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.chart-container {
grid-column: span 2;
grid-row: span 2;
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.recent-activity {
grid-column: span 2;
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
Combining Grid and Flexbox
The real power comes from combining both layout systems:
1. Grid Container with Flexbox Items
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background-color: #f8f9fa;
}
.card-content {
flex: 1;
padding: 1rem;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
border-top: 1px solid #ddd;
}
2. Responsive Layout
.layout {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr auto;
min-height: 100vh;
}
@media (min-width: 768px) {
.layout {
grid-template-columns: 250px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background-color: #333;
color: white;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
@media (min-width: 768px) {
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
}
When to Use Each
Use Flexbox When:
- You need to align items along a single axis
- Creating navigation bars or menus
- Building form layouts
- Distributing space within a component
- Creating flexible components that need to grow/shrink
Use CSS Grid When:
- You need a two-dimensional layout
- Creating page layouts
- Building card grids or galleries
- Creating dashboard layouts
- You need precise control over both rows and columns
Use Both When:
- Building complex layouts
- Creating responsive designs
- You need the best of both worlds
Best Practices
1. Start with Mobile First
/* Mobile layout */
.container {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Desktop layout */
@media (min-width: 768px) {
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}
2. Use Semantic Class Names
/* Good */
.page-layout {
}
.navigation-bar {
}
.card-grid {
}
/* Avoid */
.layout-1 {
}
.nav {
}
.grid {
}
3. Leverage CSS Custom Properties
:root {
--grid-gap: 1rem;
--border-radius: 8px;
--primary-color: #007bff;
}
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--grid-gap);
}
.card {
border-radius: var(--border-radius);
border: 1px solid var(--primary-color);
}
Conclusion
CSS Grid and Flexbox are complementary layout systems. Understanding when to use each will make you a more effective CSS developer. Remember:
- Flexbox for one-dimensional layouts and component alignment
- CSS Grid for two-dimensional layouts and page structure
- Combine both for complex, responsive layouts
- Start simple and build up complexity as needed
The key is to choose the right tool for the job and not be afraid to combine them when necessary.
Resources
Happy styling! 🎨
Project Links
Related Posts
Mastering React Hooks: A Complete Guide
Learn how to use React hooks effectively to build better components and manage state.
Getting Started with Next.js 15
Learn how to build modern web applications with Next.js 15 and the App Router.
TypeScript Best Practices for 2024
Learn the most effective TypeScript patterns and practices for building robust applications.