Flexbox vs Grid: How to Choose (With Examples)
Once you've got the hang of basic CSS, you'll run into two layout tools that seem to solve the same problem: Flexbox and Grid. Both let you arrange elements without the old hacks (floats, display: table, absolute positioning everywhere). So which one do you use?
The short answer: it depends on whether you're arranging things in one direction or two.
The one-line rule
- Flexbox is one-dimensional. It arranges items in a single row or a single column, and it's great at deciding how those items should share the available space.
- Grid is two-dimensional. It arranges items in rows and columns at the same time, and it's great when you actually care about alignment across both axes.
If you're picturing a single row of buttons, a navbar, or a list of cards that wrap onto new lines — that's Flexbox territory. If you're picturing a full page layout with a header, sidebar, main content, and footer — that's Grid territory.
Flexbox in practice
Flexbox shines when you have a row (or column) of items and want control over spacing and alignment along that one axis:
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
justify-content controls spacing along the main axis (horizontal, by default). align-items controls alignment along the cross axis (vertical, by default). This one snippet — three properties — replaces what used to take a pile of floats and clearfixes.
Flexbox is also the right tool when items need to grow or shrink to fill space:
.card {
flex: 1; /* every .card grows to share the row equally */
}
Grid in practice
Grid shines when you're defining an actual structure — rows and columns you can place things into directly:
.page-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
min-height: 100vh;
}
.sidebar { grid-area: sidebar; }
.header { grid-area: header; }
.main { grid-area: main; }
.footer { grid-area: footer; }
That grid-template-areas block reads almost like a diagram of the page — which is exactly the point. You're describing the shape of the layout, not fighting to align things piece by piece.
Grid also makes responsive card layouts trivial, without a single media query:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
This creates as many equal-width columns as fit, each at least 200px wide, and reflows automatically as the screen shrinks.
Side by side
| Question | Flexbox | Grid |
|---|---|---|
| Arranging items in one row or column? | ✅ Best fit | Works, but overkill |
| Arranging items in rows and columns together? | Possible, but awkward | ✅ Best fit |
| Items need to grow/shrink to fill space? | ✅ flex-grow / flex-shrink | Possible, but not its strength |
| Overall page layout (header/sidebar/main/footer)? | Possible, but fragile | ✅ Best fit |
| A row of buttons or a navbar? | ✅ Best fit | Overkill |
| A responsive grid of cards? | Works with flex-wrap | ✅ Cleaner, with auto-fit |
You don't have to pick just one
In real projects, Flexbox and Grid work together constantly: Grid defines the big page structure, and Flexbox handles alignment inside each grid area — like centering a button inside a header, or spacing out icons in a card footer. Neither one "wins" — they solve different-shaped problems, and most pages need both.
The fastest way to build this intuition is to ask yourself, before writing any CSS: "Am I arranging a line, or a grid?" The answer tells you which tool to reach for.