CSS Flexbox vs Grid — When to Use Which (With Examples)
The short answer: Flexbox is for laying things out in one direction (a row or a column). Grid is for laying things out in two dimensions (rows and columns together). But the real question is when each one is the better choice — and when to use both. This guide breaks it down with real examples.
The Core Difference
| Flexbox | Grid | |
|---|---|---|
| Dimensions | 1D — row OR column | 2D — rows AND columns |
| Control | Content-driven — items size themselves | Layout-driven — you define the grid structure |
| Best for | Components: navbars, cards, buttons, alignment | Page layouts: headers, sidebars, grids, dashboards |
| Item sizing | Items can grow and shrink flexibly | Cells have explicit sizes you define |
| Overlap | Not possible | Items can overlap using grid placement |
Think of it this way: Flexbox is for aligning things inside a component. Grid is for defining the overall structure of a page or section.
When to Use Flexbox
Flexbox shines when you're working in one direction and want items to flow naturally based on their content.
1. Navigation bars
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
/* Logo on the left, links in the middle, button on the right */
The nav items distribute themselves across the horizontal axis. If you add or remove items, the spacing adjusts automatically.
2. Centering anything
.center-me {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
Three lines to center horizontally and vertically. This is arguably Flexbox's most famous use case.
3. Card rows that wrap
.card-row {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 300px; /* grow, shrink, min 300px */
}
Cards fill the available width, wrapping to the next line when they can't fit at 300px minimum width.
4. Spacing items apart
.footer {
display: flex;
justify-content: space-between;
}
/* First child goes left, last goes right */
When to Use Grid
Grid is the right choice when you're defining a 2D structure — you know how many columns you want and where things should go.
1. Page layout (header, sidebar, main, footer)
.page {
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; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Named grid areas make the layout readable. You can rearrange the entire page by changing the grid-template-areas string — no HTML changes needed.
2. Responsive card grid (no media queries)
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
This is Grid's killer feature. The browser automatically calculates how many columns fit, with each card at least 280px wide. No media queries, no JavaScript. This single line replaces hundreds of lines of responsive CSS.
3. Dashboard layouts
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto;
gap: 16px;
}
.widget-wide { grid-column: span 2; }
.widget-tall { grid-row: span 2; }
Widgets can span multiple columns and rows, creating complex dashboard layouts with minimal CSS.
4. Equal-height columns
.equal-cols {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
}
Grid cells are equal height by default. In Flexbox, you need align-items: stretch and it only works in the cross axis.
When to Use Both Together
The best layouts use Grid for the overall page structure and Flexbox for component-level alignment inside grid cells. They're not competitors — they're complementary.
/* Grid for the page */
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr;
}
/* Flexbox for the navbar inside the header */
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
}
/* Flexbox for button groups inside grid cells */
.actions {
display: flex;
gap: 8px;
justify-content: flex-end;
}
Side-by-Side Comparison
| Task | Use | Why |
|---|---|---|
| Center a div | Flexbox | 3 lines, one direction |
| Navigation bar | Flexbox | Horizontal alignment, variable items |
| Page layout with sidebar | Grid | 2D structure with named areas |
| Responsive card gallery | Grid | auto-fit + minmax handles columns |
| Form label + input alignment | Grid | Labels in column 1, inputs in column 2 |
| Button group (row of buttons) | Flexbox | Horizontal flow with gap |
| Dashboard with mixed-size widgets | Grid | span across rows and columns |
| Vertically stacking items | Flexbox | flex-direction: column |
| Photo gallery with exact proportions | Grid | Precise row/column sizing |
| Footer with spread-out links | Flexbox | justify-content: space-between |
Key Properties at a Glance
Flexbox (parent)
| Property | What it does |
|---|---|
flex-direction | row (horizontal) or column (vertical) |
justify-content | Alignment along the main axis |
align-items | Alignment along the cross axis |
flex-wrap | Allow items to wrap to new lines |
gap | Space between items |
Grid (parent)
| Property | What it does |
|---|---|
grid-template-columns | Defines column sizes |
grid-template-rows | Defines row sizes |
grid-template-areas | Named layout regions |
gap | Space between cells |
place-items | Shorthand for align + justify items |
Common Mistakes
- Using Grid for a navbar — you'd need to know the exact number of columns up front. Flexbox handles variable items naturally.
- Using Flexbox for a page layout — nesting flex containers to simulate rows and columns is fragile. Grid handles it natively.
- Forgetting
flex-wrap— without it, Flexbox squishes items to fit one line. Addflex-wrap: wrapfor responsive behavior. - Fixed widths in Grid — using
pxinstead offrmakes Grid layouts break on different screen sizes. Usefrfor flexible columns. - Not using
gap— beforegapexisted, developers used margin hacks. Thegapproperty is supported in both Flexbox and Grid and is much cleaner. - Choosing one or the other — the best solution is usually both. Grid for structure, Flexbox for components within grid cells.
The Decision Flowchart
When you're unsure which to use, ask these questions:
- Am I laying out items in one direction (a row OR a column)? → Flexbox
- Do I need to control rows AND columns simultaneously? → Grid
- Should the content determine the size of items? → Flexbox
- Do I want to define the layout structure first, then place items? → Grid
- Do I need items to overlap or span multiple rows/columns? → Grid
When in doubt, try both in our visual generators and see which feels right for your use case.
Frequently Asked Questions
Can I use Flexbox inside a Grid cell?
Yes — this is the recommended approach. Use Grid for page-level layout and Flexbox for component alignment inside individual grid cells.
Is one faster than the other?
Performance differences are negligible for typical layouts. Both are hardware-accelerated in modern browsers. Choose based on the layout problem, not performance.
Does Grid replace Flexbox?
No. Grid is better for 2D layouts, but Flexbox is simpler and more natural for 1D alignment tasks. They solve different problems and work best together.
What is fr and how is it different from %?
fr stands for "fraction of available space." Unlike %, it accounts for gap and other fixed-size tracks automatically. 1fr 2fr means the second column gets twice the remaining space after gaps are subtracted.
Build Flexbox and CSS Grid layouts with live preview and copy the generated CSS. Runs 100% in your browser.
Flexbox Generator → CSS Grid Generator →