Tech Tutorials

CSS Grid vs Flexbox: When to Use Each

A comprehensive comparison of CSS Grid and Flexbox, with practical examples and use cases.

D
Developer Blog
January 25, 20246 min read

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! 🎨

Related Posts