CSS Grid vs Flexbox: When to Use Each Layout System
The Core Difference: 1D vs 2D Layout
The fundamental distinction between Flexbox and CSS Grid is dimensionality. Flexbox is a one-dimensional layout system -- it handles either a row or a column at a time. CSS Grid is a two-dimensional layout system -- it handles rows and columns simultaneously. This difference determines which tool fits each layout problem.
Flexbox excels when content flows in a single direction: navigation bars, button groups, form controls, and media objects. Grid excels when you need to control placement in both directions: page layouts, dashboards, image galleries, and data tables. Most modern interfaces use both: Grid for the macro layout, Flexbox for micro alignment within components.
Feature Comparison
| Feature | Flexbox | CSS Grid |
|---|---|---|
| Dimensions | 1D (row OR column) | 2D (rows AND columns) |
| Content vs Layout | Content-driven sizing | Layout-driven sizing |
| Item placement | Sequential flow | Explicit row/column placement |
| Gaps | gap property | gap, row-gap, column-gap |
| Alignment | justify-content, align-items | All flex alignments + place-items, place-content |
| Overlap | Not possible (without position) | Items can overlap via grid-area |
| Named areas | No | grid-template-areas |
| Browser support | 99%+ | 97%+ |
Flexbox Essentials
Flexbox distributes space along a single axis. Set display: flex on the container and control direction, wrapping, alignment, and sizing of child items.
Navigation Bar
/* Navbar: logo left, links right */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
gap: 1rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.navbar {
flex-direction: column;
align-items: flex-start;
}
}Centering Content
/* Perfect centering -- the classic Flexbox win */
.centered-container {
display: flex;
justify-content: center; /* horizontal */
align-items: center; /* vertical */
min-height: 100vh;
}
/* Button group with equal spacing */
.button-group {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.button-group > button {
flex: 1; /* equal width buttons */
min-width: 120px; /* prevent too-narrow buttons */
}Media Object Pattern
/* Image + text side by side */
.media-object {
display: flex;
gap: 1rem;
align-items: flex-start;
}
.media-object img {
flex-shrink: 0; /* prevent image from shrinking */
width: 80px;
height: 80px;
border-radius: 8px;
object-fit: cover;
}
.media-object .content {
flex: 1; /* text takes remaining space */
min-width: 0; /* prevent overflow with long text */
}CSS Grid Essentials
CSS Grid defines rows and columns simultaneously, then places items into the resulting cells. It is the right tool when you think in terms of a grid structure rather than content flow.
Page Layout with Named Areas
/* Classic page layout: header, sidebar, main, footer */
.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;
gap: 0;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Responsive: single column on mobile */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}Responsive Card Grid (No Media Queries)
/* Auto-responsive card grid using auto-fill + minmax */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
padding: 1.5rem;
}
/* Each card fills one grid cell */
.card {
border: 1px solid var(--color-border);
border-radius: 12px;
padding: 1.5rem;
background: var(--color-surface);
}
/* Result:
- 4 columns on desktop (1200px+)
- 3 columns on tablet (900px)
- 2 columns on small tablet (600px)
- 1 column on mobile (< 320px)
All without a single media query! */Dashboard Layout
/* Dashboard with featured widget spanning 2 columns */
.dashboard {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.widget-featured {
grid-column: span 2; /* spans 2 columns */
grid-row: span 2; /* spans 2 rows */
}
.widget-tall {
grid-row: span 2; /* double height */
}
/* Responsive: stack on tablet */
@media (max-width: 900px) {
.dashboard {
grid-template-columns: repeat(2, 1fr);
}
.widget-featured {
grid-column: span 2;
grid-row: span 1;
}
}
@media (max-width: 600px) {
.dashboard {
grid-template-columns: 1fr;
}
.widget-featured,
.widget-tall {
grid-column: span 1;
grid-row: span 1;
}
}When to Use Each: Decision Guide
| Use Case | Best Choice | Why |
|---|---|---|
| Navigation bar | Flexbox | Single row of items with variable spacing |
| Page layout (header/sidebar/main) | Grid | 2D layout with named areas |
| Card grid | Grid | auto-fill + minmax for responsive columns |
| Centering content | Flexbox | Simplest centering solution |
| Form layout | Grid | Align labels and inputs in columns |
| Button group | Flexbox | Inline items with gap and wrapping |
| Dashboard widgets | Grid | Items spanning multiple rows/columns |
| Tag/chip list | Flexbox | Wrapping inline items with flex-wrap |
You can quickly prototype and test CSS layouts using our code formatting tools to keep your stylesheets clean. For color values in your layouts, check our guide on CSS color formats.
Combining Grid and Flexbox
The most effective approach uses both systems together. Grid handles the macro layout while Flexbox handles micro alignment within grid items.
/* Grid for overall layout */
.app-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
min-height: 100vh;
}
/* Flexbox inside the header (a grid item) */
.app-header {
grid-column: 1 / -1; /* span all columns */
display: flex; /* Flexbox inside Grid! */
justify-content: space-between;
align-items: center;
padding: 0 1.5rem;
}
/* Flexbox inside sidebar navigation */
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.25rem;
padding: 1rem;
}
/* Grid for the main content cards */
.main-content {
display: grid; /* Nested Grid! */
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
padding: 1.5rem;
align-content: start;
}
/* Flexbox inside each card */
.card-inner {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto; /* push footer to bottom */
}Common Layout Pitfalls
- Using Grid for 1D layouts -- if you only need items in a row, Flexbox is simpler.
display: flex; gap: 1rem;beatsdisplay: grid; grid-auto-flow: column;every time. - Forgetting min-width: 0 on Flexbox children -- flex items default to
min-width: auto, which prevents text truncation. Addmin-width: 0to allow overflow handling. - Not using the gap property -- many developers still use margins for spacing. The
gapproperty works on both Grid and Flexbox and avoids the double-margin problem. - Over-nesting Grid containers -- deep nesting creates complexity. Use
subgrid(supported in modern browsers) to inherit parent grid tracks instead of creating a new grid context. - Causing layout shifts (CLS) -- always define explicit sizes for grid items that load content asynchronously (images, ads). Undefined dimensions cause content to shift, hurting your Core Web Vitals score.
Subgrid: The Missing Feature
Subgrid (part of CSS Grid Level 2) lets a nested grid inherit its parent's track sizing. This solves the long-standing problem of aligning items across sibling grid cells -- for example, making all card titles and descriptions line up perfectly regardless of content length.
/* Parent grid */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
/* Each card inherits parent's row tracks */
.card {
display: grid;
grid-row: span 3; /* card occupies 3 rows */
grid-template-rows: subgrid; /* inherit parent row sizing */
gap: 0;
}
/* All card titles align, all descriptions align, all CTAs align */
.card-title { /* row 1 */ }
.card-description { /* row 2 */ }
.card-cta { /* row 3 */ align-self: end; }
/* Browser support (2026): Chrome 117+, Firefox 71+, Safari 16+ */Frequently Asked Questions
Can I use CSS Grid and Flexbox together?
Is CSS Grid supported in all browsers?
Which is better for responsive design: Grid or Flexbox?
repeat(auto-fill, minmax(280px, 1fr)) is the cleanest solution.Format Your CSS Code
Keep your stylesheets clean and readable. Use our free JSON Formatter for config files, or check color values with our Color Picker tool. All tools run entirely in your browser.
Open JSON Formatter