Flexbox vs grid.
One dimension or two.
The most-asked CSS layout question. Both are layout systems. Both are modern. Both should be in your toolkit. The difference is simple: flexbox is one-dimensional — items in a row or a column. Grid is two-dimensional — items in rows and columns together. Flexbox adapts to content. Grid defines the structure first. Use both. This page covers when each wins and how they compose.
Short answer: Use flexbox for a single row or column — nav bars, button groups, card content, toolbars, centered content. Use grid for two-dimensional layout — page layout, dashboard panels, image galleries, any grid of cells. In practice: grid for the page skeleton, flexbox for the components inside. They compose — a grid item can be a flex container, and vice versa. Learn both, use both.
✅ The rule
One question decides it: is the layout 1D or 2D?
Flexbox = 1D
Items flow in a single row or column. Content-driven: items decide their size, the container adapts.
Grid = 2D
Items flow in rows and columns. Structure-driven: the container defines the grid, items fill it.
Flexbox for content
Unknown number of items — tags, nav links, buttons that wrap. Let items size themselves.
Grid for layout
Known structure — header, sidebar, main, footer. Define the tracks, place items into them.
✅ Flexbox — where it wins
A single-axis toolbar.
.toolbar {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1rem;
background: white;
border-bottom: 1px solid #ddd;
}
.toolbar__title {
margin-right: auto; /* push actions to the right */
font-weight: 600;
}
.toolbar__button {
padding: 0.5rem 0.75rem;
border: 1px solid #ddd;
background: white;
border-radius: 4px;
}
✅ One row, items side by side. ✅ align-items: center — vertical alignment free. ✅ gap: 0.5rem — consistent spacing without margin. ✅ margin-right: auto — pushes title left, buttons right. ✅ Unknown number of buttons — flex handles it. Why flexbox: single axis, content-driven. Each item sizes itself; the container adapts. The same toolbar in grid would be more code and would require knowing the number of items.
✅ Grid — where it wins
A two-dimensional page layout.
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 80px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
}
✅ Two-dimensional: rows AND columns. ✅ grid-template-areas — visual layout map. ✅ Each element knows its area by name. ✅ One media query flips the layout to mobile. ✅ gap handles spacing between every cell. Why grid: structure-driven. The container defines the grid; items fill cells. The same layout in flexbox would need nested flex containers (header + content-row + footer, with content-row split into sidebar + main). Doable, but more code and harder to reason about. This is the layout grid was designed for.
✅ Using both together
The pattern every real site uses.
/* Page skeleton — grid */
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas:
"header header"
"sidebar main";
}
/* Header inside — flexbox */
.header {
grid-area: header;
display: flex;
align-items: center;
justify-content: space-between;
}
/* Card grid — grid */
.card-grid {
grid-area: main;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
}
/* Card content — flexbox */
.card {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.card__actions {
display: flex;
gap: 0.5rem;
margin-top: auto;
}
.layout → grid (2D page structure) .header → flexbox (row of logo + nav) .card-grid → grid (auto-fill columns) .card → flexbox (column of content) .card__actions → flexbox (row of buttons) ✅ Grid for structure. ✅ Flexbox for content inside. ✅ Both used, both necessary. ✅ The card grid is responsive without media queries — auto-fill + minmax handles it. This is the pattern modern sites use. Not "flexbox or grid" — "flexbox AND grid, each where it fits."
Don't use grid for a single row. If you have three buttons in a row, flexbox is the right tool — it's simpler, has less mental overhead, and handles unknown item counts naturally. Grid is a two-dimensional layout system; using it for a one-dimensional row is like using a spreadsheet for a grocery list. The rule of thumb: if you can describe the layout as "items in a row" or "items in a column," use flexbox. If you need both rows and columns, use grid. Most components inside a page are flexbox; the page itself is grid.
⚠️ Common mistakes
The flexbox-vs-grid mistakes that cost real time.
Overkill. Fix: flexbox.
Needs nested flex containers. Fix: grid with grid-template-areas.
You end up writing worse CSS. Fix: learn both. Use each where it fits.
Legacy pattern. Fix: flexbox or grid.
gapAdding margin to every item instead. Fix: gap on the container — works in both flex and grid.
Overcomplicated. Fix: check if the layout is actually 2D — if so, one grid beats three flexes.
Grid needs defined tracks. Fix: flexbox with flex-wrap.
flex-wrap works but grid is cleaner. Fix: display: grid; grid-template-columns: 1fr 1fr;
❓ Frequently asked
What is the difference between flexbox and grid?
Flexbox is one-dimensional — it lays out items along a single axis (row or column). Grid is two-dimensional — it lays out items in rows and columns simultaneously. Flexbox is content-out: items decide their size, the container adapts. Grid is layout-in: the container defines the tracks, and items fit into them. Use flexbox for navigation bars, button groups, card content. Use grid for page layouts, dashboard panels, image galleries.
Can I use flexbox and grid together?
Yes, and you should. They solve different problems and compose well. A common pattern: grid for the page layout (sidebar + main + footer), flexbox for the navigation inside the header, flexbox for the card content, grid for the card grid. They are not competing tools — they're complementary. A grid item can be a flex container, and a flex item can be a grid container. Most real layouts use both.
When should I use grid instead of flexbox?
Use grid when you know the layout structure and need items to align in both rows and columns. Examples: page layout, dashboard with fixed panels, image gallery with equal cells, form with aligned labels and inputs. Also use grid when you want to define the columns first and let items auto-place into them. Grid is best when the layout is designed; flexbox is best when the layout adapts to content.
When should I use flexbox instead of grid?
Use flexbox for one-dimensional layouts where items are in a single row or column. Examples: navigation menu, button group, toolbar, card header with title and action, form row with label and input, centered content. Flexbox is also better when the number of items is unknown or dynamic — like tags in a container that wrap. Grid needs you to define tracks; flexbox lets items size themselves. When the layout is content-driven, flexbox wins.
Is flexbox or grid better for responsive design?
Both work well, but grid is often better for complex responsive layouts because you can redefine the entire grid at a breakpoint (grid-template-columns: 1fr → 1fr 1fr → 1fr 1fr 1fr) in one line. Flexbox is better for responsive content that flows — like a wrapping tag list — because flex-wrap handles the reflow automatically. For most layouts, use grid for the page structure and flexbox for the components inside.
Does grid replace flexbox?
No. Grid and flexbox are complementary, not replacements. Flexbox is better for one-dimensional content-driven layout. Grid is better for two-dimensional structure-driven layout. Every real layout uses both — grid for the page skeleton, flexbox for the components. Even in a grid-heavy design, the header, nav, and cards inside grid cells are flexbox. You need to know both.