7 min read By Sarah Chen

CSS Grid vs Flexbox: When to Use Each

Master CSS layout with this comprehensive guide to Grid and Flexbox. Learn when to use each layout system and how to combine them effectively.

CSS Grid Flexbox Layout Design
CSS Grid vs Flexbox: When to Use Each

The Core Difference

Flexbox is one-dimensional (row OR column) Grid is two-dimensional (rows AND columns)

When to Use Flexbox

Flexbox excels at distributing items along a single axis.

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
}

Card Content

.card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.card-content {
  flex: 1; /* Grows to fill space */
}

.card-actions {
  margin-top: auto; /* Push to bottom */
}

Centering Content

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

Form Controls

.form-group {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.form-group label {
  flex-shrink: 0;
  width: 120px;
}

.form-group input {
  flex: 1;
}

When to Use Grid

Grid is perfect for two-dimensional layouts.

Page Layouts

.layout {
  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;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

Image Galleries

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* Pinterest-style masonry (with grid) */
.masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 10px;
  gap: 1rem;
}

.masonry-item {
  grid-row-end: span var(--row-span);
}

Card Grids

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 2rem;
}

/* Responsive without media queries! */

Dashboard Layouts

.dashboard {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1.5rem;
}

.widget-large {
  grid-column: span 8;
}

.widget-small {
  grid-column: span 4;
}

.widget-full {
  grid-column: 1 / -1;
}

Flexbox Deep Dive

Main Properties

.flex-container {
  display: flex;
  
  /* Direction */
  flex-direction: row | row-reverse | column | column-reverse;
  
  /* Wrapping */
  flex-wrap: nowrap | wrap | wrap-reverse;
  
  /* Main axis alignment */
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
  
  /* Cross axis alignment */
  align-items: stretch | flex-start | flex-end | center | baseline;
  
  /* Multi-line cross axis */
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
  
  /* Gap (modern) */
  gap: 1rem;
}

Item Properties

.flex-item {
  /* Growth factor */
  flex-grow: 0; /* default */
  
  /* Shrink factor */
  flex-shrink: 1; /* default */
  
  /* Base size */
  flex-basis: auto; /* default */
  
  /* Shorthand */
  flex: 1; /* grow shrink basis */
  flex: 0 0 200px; /* fixed width */
  
  /* Individual alignment */
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
  
  /* Order */
  order: 0; /* default */
}

Practical Flexbox Patterns

/* Equal width columns */
.columns {
  display: flex;
}

.column {
  flex: 1;
}

/* Sidebar layout */
.layout {
  display: flex;
}

.sidebar {
  flex: 0 0 250px;
}

.main {
  flex: 1;
}

/* Sticky footer */
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.content {
  flex: 1;
}

/* Holy grail layout */
.holy-grail {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.hg-body {
  display: flex;
  flex: 1;
}

.hg-sidebar {
  flex: 0 0 200px;
  order: -1;
}

.hg-content {
  flex: 1;
}

.hg-aside {
  flex: 0 0 200px;
}

Grid Deep Dive

Defining Grids

.grid {
  display: grid;
  
  /* Columns */
  grid-template-columns: 200px 1fr 200px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-template-columns: 1fr 2fr 1fr;
  
  /* Rows */
  grid-template-rows: auto 1fr auto;
  grid-auto-rows: minmax(100px, auto);
  
  /* Gaps */
  gap: 1rem;
  column-gap: 2rem;
  row-gap: 1rem;
  
  /* Areas */
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}

Placing Items

.grid-item {
  /* Line-based placement */
  grid-column: 1 / 3;
  grid-row: 2 / 4;
  
  /* Span */
  grid-column: span 2;
  grid-row: span 3;
  
  /* Shorthand */
  grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
  
  /* Named area */
  grid-area: header;
}

Alignment

.grid {
  /* Align items (within their cell) */
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
  place-items: center; /* both */
  
  /* Align grid (within container) */
  justify-content: start | end | center | stretch | space-between | space-around | space-evenly;
  align-content: start | end | center | stretch | space-between | space-around | space-evenly;
  place-content: center; /* both */
}

.grid-item {
  /* Individual alignment */
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
  place-self: center; /* both */
}

Advanced Grid Patterns

/* Responsive grid without media queries */
.auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 1rem;
}

/* RAM (Repeat, Auto, Minmax) */
.ram {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* Sidebar always visible */
.sidebar-grid {
  display: grid;
  grid-template-columns: minmax(200px, 300px) minmax(0, 1fr);
}

/* Asymmetric grid */
.asymmetric {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-auto-rows: minmax(150px, auto);
}

Combining Grid and Flexbox

Often the best solution uses both!

/* Grid for overall layout */
.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "footer";
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* Flexbox for header */
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
}

/* Grid for main content */
.main {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

/* Flexbox for cards */
.card {
  display: flex;
  flex-direction: column;
}

.card-body {
  flex: 1;
}

.card-actions {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
}

Real-World Examples

Blog Layout

.blog-layout {
  display: grid;
  grid-template-columns: 1fr min(65ch, 100%) 1fr;
}

.blog-layout > * {
  grid-column: 2;
}

.full-bleed {
  grid-column: 1 / -1;
}

Pricing Cards

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 2rem;
}

.pricing-card {
  display: flex;
  flex-direction: column;
  padding: 2rem;
  border: 1px solid #ddd;
  border-radius: 8px;
}

.pricing-features {
  flex: 1;
  margin: 2rem 0;
}

.pricing-cta {
  margin-top: auto;
}

Responsive Navigation

.nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  list-style: none;
}

@media (max-width: 768px) {
  .nav {
    flex-direction: column;
  }
  
  .nav-links {
    flex-direction: column;
    width: 100%;
  }
}

Performance Tips

/* Avoid unnecessary grid items */
/* Bad */
.wrapper {
  display: grid;
}

.wrapper > div {
  /* Each div is a grid item */
}

/* Good - only when needed */
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

/* Use gap instead of margins */
/* Bad */
.grid > * {
  margin: 1rem;
}

/* Good */
.grid {
  gap: 1rem;
}

Browser Support

Both Grid and Flexbox have excellent browser support:

  • Flexbox: 98%+ support
  • Grid: 96%+ support

Use feature queries for fallbacks:

.layout {
  /* Flexbox fallback */
  display: flex;
  flex-wrap: wrap;
}

@supports (display: grid) {
  .layout {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}

Quick Decision Guide

Use Flexbox when:

  • Content flows in one direction
  • Items should wrap
  • You need flexible spacing
  • Centering content
  • Navigation menus

Use Grid when:

  • Two-dimensional layout needed
  • Complex alignment required
  • Overlapping elements
  • Responsive design without media queries
  • Page layouts

Conclusion

Both Grid and Flexbox are powerful tools in modern CSS. Understanding when to use each—and how to combine them—is key to creating flexible, maintainable layouts. Start with Grid for page structure, then use Flexbox for component internals.

S

Sarah Chen

Published on March 1, 2024

Share: