The "Grid vs Flexbox" debate comes up constantly — and it's usually the wrong question. They're not competing tools, they're complementary ones. Grid and Flexbox solve different layout problems, and using them together is normal and correct. The skill is knowing which problem each one is designed to solve.
The Flexbox Visualizer and CSS Grid Generator let you experiment with both visually — tweak values and see results without writing a line of code.
The Core Distinction
Here's the cleanest way to think about it:
- Flexbox is one-dimensional. It lays items out in a row or a column. Items flow in one direction and the layout adapts to the content.
- Grid is two-dimensional. It defines explicit rows and columns simultaneously, giving you precise control over placement in both directions.
A navbar is one row of items — Flexbox. A full page layout with header, sidebar, main content, and footer — Grid. A card grid that wraps to multiple rows — could be either, depending on whether rows need to align across cards.
When to Use Flexbox
Navigation Bars
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}
A navbar is fundamentally a single row of items. Flexbox handles the spacing, alignment, and reordering perfectly. The logo goes left, nav links go right — justify-content: space-between handles it with one line.
Button Groups and Icon Rows
.button-group {
display: flex;
gap: 8px;
align-items: center;
}
Any time you're lining up a small set of elements in a row or column — buttons, icons, tags, badges — Flexbox is the natural fit.
Centering a Single Item
.centered {
display: flex;
justify-content: center;
align-items: center;
}
The classic two-line perfect centering. Works horizontally and vertically in any container height. Grid can do this too (place-items: center), but Flexbox is typically already in context.
Wrapping Tag Clouds
.tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
When you have a variable number of items that should flow and wrap naturally — tags, chips, filters — Flexbox with flex-wrap: wrap is ideal. Items flow left to right and wrap when they run out of space, with no fixed column structure needed.
When to Use Grid
Page-Level Layouts
.page {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
Named grid areas make page structure readable and maintainable. This is the kind of two-dimensional layout Grid was designed for — rows and columns working together, not just one direction.
Card Grids With Aligned Rows
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
The auto-fill + minmax pattern is one of the most powerful things in modern CSS. It creates as many columns as will fit at the minimum width, then stretches them to fill the remaining space — fully responsive with zero media queries. Cards in the same row automatically share the same height.
Dashboard Layouts
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 16px;
}
.widget-full { grid-column: span 12; }
.widget-half { grid-column: span 6; }
.widget-third { grid-column: span 4; }
A 12-column grid system gives you the flexibility of Bootstrap-style layouts without the framework. Widgets span as many columns as needed, and Grid handles all the alignment math.
The Decision Flowchart
| Question | Answer | Use |
|---|---|---|
| Do items flow in one direction? | Yes | Flexbox |
| Do you need rows AND columns? | Yes | Grid |
| Should rows align across items? | Yes | Grid |
| Is content quantity variable/unknown? | Yes | Flexbox |
| Do you need precise placement control? | Yes | Grid |
| Is it a simple centering problem? | Yes | Either (Flexbox is common) |
Using Both Together
The most powerful layouts use Grid for macro structure and Flexbox for micro-layout within components. A typical pattern:
/* Grid for the overall page structure */
.page {
display: grid;
grid-template-columns: 260px 1fr;
gap: 24px;
}
/* Flexbox for the navbar inside the header */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
/* Grid for the card grid in main content */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
/* Flexbox for layout inside each card */
.card {
display: flex;
flex-direction: column;
gap: 12px;
}