Articles › CSS & Web Design
CSS Flexbox vs Grid: A Practical Guide to Modern Layouts
Learn when to use Flexbox and when to use CSS Grid, with practical patterns for navbars, cards, holy-grail layouts, responsive grids and centering — without media query overload.
Flexbox and CSS Grid replaced a decade of float hacks and clearfixes. Together they can build virtually any layout with a few lines of CSS. The question developers ask most is which one should I use? This guide answers that with clear rules and copy-ready patterns.
The one-sentence difference
- Flexbox is one-dimensional: it lays items out in a row or a column and distributes space along that line.
- Grid is two-dimensional: it defines rows and columns at the same time and places items into that structure.
A practical heuristic: Flexbox is content-out (items decide their size, the container distributes leftovers); Grid is layout-in (the container defines tracks, items fill them).
Flexbox essentials
.toolbar {
display: flex;
flex-direction: row; /* row | column */
justify-content: space-between; /* main axis */
align-items: center; /* cross axis */
gap: 12px;
flex-wrap: wrap;
}
The two axes are the key concept:
| Property | Axis | Common values |
|---|---|---|
justify-content |
main axis | flex-start, center, space-between, space-around |
align-items |
cross axis | stretch, center, flex-start, baseline |
align-self |
cross axis (one item) | same as align-items |
The flex shorthand
Each child can grow, shrink and have a base size:
.item { flex: 1 1 200px; } /* grow, shrink, basis */
flex: 1— share the remaining space equally.flex: none— keep the natural size.flex: 0 0 280px— a fixed-width sidebar.
Tip: If a flex item with long text refuses to shrink, add
min-width: 0. Flex items default tomin-width: auto, which prevents them from shrinking below their content.
Flexbox patterns
Navbar with a pushed-right action:
.nav { display: flex; align-items: center; gap: 16px; }
.nav__actions { margin-inline-start: auto; } /* pushes to the end — RTL-friendly */
Perfect centering:
.center { display: flex; justify-content: center; align-items: center; min-height: 100vh; }
Cards with buttons stuck to the bottom:
.card { display: flex; flex-direction: column; }
.card__footer { margin-top: auto; }
Grid essentials
.dashboard {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr auto;
gap: 16px;
min-height: 100vh;
}
The fr unit means "a fraction of the free space". 1fr 2fr gives the second column twice the space of the first.
Named template areas
Grid areas make complex layouts readable — the CSS literally draws the layout:
.page {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "header" "main" "sidebar" "footer";
}
}
Changing the layout on mobile only requires redrawing the areas.
The responsive grid without media queries
This single line creates a card grid that adapts to any width:
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 20px;
}
minmax(260px, 1fr)— each column is at least 260px and can grow.auto-fill— creates as many columns as fit.auto-fit— likeauto-fill, but collapses empty tracks so existing items stretch.
Spanning and placing items
.featured {
grid-column: span 2;
grid-row: span 2;
}
.full-width { grid-column: 1 / -1; } /* from first to last line */
This is how "bento" layouts with a large featured card are built.
Flexbox or Grid? A decision table
| Situation | Choose |
|---|---|
| Navbar, toolbar, button group | Flexbox |
| Centering a single element | Either (Grid: place-items: center) |
| Items of unknown size wrapping naturally (tags, chips) | Flexbox |
| Card gallery with equal columns | Grid |
| Whole-page layout (header/sidebar/main/footer) | Grid |
| Aligning content inside a card | Flexbox |
| Items that must line up in both rows and columns | Grid |
In real projects you combine them: Grid for the page and card gallery, Flexbox inside each card and for the navbar.
Writing layouts that work in RTL
Persian, Arabic and Hebrew sites are right-to-left. Use logical properties and your layout flips automatically when dir="rtl":
| Physical | Logical |
|---|---|
margin-left |
margin-inline-start |
padding-right |
padding-inline-end |
left: 0 |
inset-inline-start: 0 |
border-left |
border-inline-start |
text-align: left |
text-align: start |
Flexbox and Grid already follow the writing direction: justify-content: flex-start means "right" in RTL. Avoid row-reverse hacks for RTL — logical properties are cleaner.
Subgrid and container queries
Two newer features are now supported in all modern browsers:
Subgrid lets nested elements align to the parent grid — perfect for cards whose titles, text and buttons should line up across a row:
.cards { display: grid; grid-template-columns: repeat(3, 1fr); }
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
}
Container queries let a component adapt to its container's width instead of the viewport:
.card-wrapper { container-type: inline-size; }
@container (min-width: 420px) {
.card { display: grid; grid-template-columns: 140px 1fr; }
}
Common mistakes
- Using
width: 33.33%with margins instead ofgap. - Forgetting
min-width: 0on flex items with long text or code. - Building page layouts with nested flex rows instead of a grid.
- Using physical properties (
left,margin-right) in bilingual sites. - Too many breakpoints —
auto-fill+minmaxoften removes the need for them.
Summary
Use Flexbox to align and distribute items along a line, and Grid to define two-dimensional structures. Combine them freely, rely on gap, fr, minmax and named areas, and write logical properties so your layouts work in both LTR and RTL. With these tools you'll rarely need a CSS framework for layout.
FAQ
Is Grid slower than Flexbox?
No meaningful difference in real-world pages. Choose based on the layout problem, not performance.
Should I still use a framework like Bootstrap for grids?
Not for layout alone. Native Grid is more powerful and needs less markup. Frameworks still help with design systems and components.
Can Flexbox replace Grid?
For simple rows, yes. But two-dimensional layouts built with Flexbox need extra wrappers and fragile widths — Grid solves them directly.