CSS layout comparison
CSS Grid vs Flexbox
The two modern CSS layout systems every front-end developer uses daily. They solve overlapping problems, which creates confusion about when to reach for each one — and the answer is usually "both, but for different levels of the layout."
TL;DR
- Flexbox is one-dimensional. It arranges items in a row or a column. Great for navigation bars, button groups, centering, and any component-level alignment.
- CSS Grid is two-dimensional. It controls rows and columns at the same time. Great for page layouts, card grids, and any design where items need to align on both axes.
- Use both. Grid for the overall layout; Flexbox inside the cells. They are designed to complement each other.
Side-by-side comparison
| Aspect | CSS Grid | Flexbox |
|---|---|---|
| Dimensions | Two-dimensional (rows AND columns) | One-dimensional (row OR column) |
| Placement | Items can be placed in named areas or by line numbers | Items flow along a single axis; wrapping allowed |
| Use case | Page layout, image galleries, data tables | Navigation, button groups, centering, card internals |
| Alignment | Align items on both axes simultaneously | Align items on main axis and cross axis separately |
| Sizing unit | fr unit — fractions of available space | flex-grow / flex-shrink / flex-basis |
| Browser support | All modern browsers (since 2017) | Slightly broader (IE 11 with prefixes) |
| Learning curve | Steeper — two axes, named areas, fr unit | Gentler — one axis, intuitive properties |
| Responsive design | repeat(auto-fit, minmax()) for fluid grids | flex-wrap: wrap for wrapping rows |
Code side-by-side
A classic page layout (header, sidebar, content, footer):
CSS Grid (page layout)
.page {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: content; }
footer { grid-area: footer; } Flexbox (navbar items)
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 1rem;
gap: 0.5rem;
}
.navbar-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
/* Centre a single element: */
.card {
display: flex;
align-items: center;
justify-content: center;
} When to use CSS Grid
- Page-level layout. Headers, sidebars, main content areas, and footers all align on both axes — Grid handles this in a few lines with
grid-template-areas. - Card grids and galleries.
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))creates a fluid, responsive grid with no media queries. - Overlapping elements. Grid items can share cells; Flexbox cannot overlap items without absolute positioning.
- Alignment across multiple rows. If items in different rows need to align with each other, only Grid can do this reliably.
When to use Flexbox
- Navigation bars. Logo on the left, links in the middle, CTA on the right —
justify-content: space-betweenhandles this perfectly. - Centring a single element. The classic
display: flex; align-items: center; justify-content: centeris the simplest vertical-and-horizontal centring solution. - Button groups and toolbars. Items naturally size to content and flow in a row; Flexbox keeps them aligned without manual sizing.
- Inside Grid cells. Use Flexbox to arrange the contents of a grid area — the two work perfectly together.
English phrases engineers use
CSS Grid conversations
- "I used named grid areas so the markup reads like a wireframe."
- "The columns are set to repeat(auto-fit, minmax(200px, 1fr)) — fully responsive."
- "That element needs to span two columns:
grid-column: span 2." - "Grid gives us two-dimensional alignment — rows and columns at once."
- "Use
gapinstead of margins — it's gap-aware."
Flexbox conversations
- "Just flex the container and set
align-items: center." - "The items shrink to fit because flex-shrink defaults to 1."
- "Add flex: 1 to the main content so it fills the remaining space."
- "Set flex-wrap: wrap so items break onto the next row on mobile."
- "The main axis is horizontal here — use justify-content to space items."
Quick decision tree
- Overall page structure (header, sidebar, footer) → CSS Grid
- Navigation bar, toolbar, button group → Flexbox
- Responsive card grid / image gallery → CSS Grid
- Centre one element (vertically + horizontally) → Flexbox
- Items that must align across rows → CSS Grid
- Simple single-row / single-column layout → Flexbox
- Inside a grid cell to arrange its contents → Flexbox inside Grid
Common Mistakes and Trade-offs
A remarkably common mistake we see developers make when initially considering Grid vs. Flexbox is assuming that because Grid excels at two-dimensional layouts, it automatically replaces Flexbox for one-dimensional scenarios. This leads to over-engineering complex grid setups where a simple flex container would have been far more efficient and maintainable. The truth is, both systems are fundamentally designed for specific layout needs; attempting to shoehorn Grid into every situation simply introduces unnecessary complexity without any real benefit. It's crucial to understand the core purpose of each system before applying it – don't force a solution where a simpler approach exists.
At scale, particularly with large, dynamic content sets or complex component hierarchies, Flexbox's performance can become a significant bottleneck. Grid relies heavily on creating a fixed grid structure which involves more recalculations as the screen size changes, especially when dealing with numerous items that need to be dynamically sized and positioned. While Grid's implicit sizing is powerful, the underlying calculations still add up. Flexbox, while still requiring careful optimization, often offers better performance in scenarios where you're primarily managing item distribution along a single axis – think of a carousel or a responsive navigation bar with varying content lengths. Benchmarking becomes essential to truly understand the impact.
There's a pervasive misconception that Grid is 'always better' for overall page layouts because it can handle both rows and columns directly. This ignores the fact that modern web design increasingly involves complex, nested component arrangements—often built using Flexbox within a Grid container. Attempting to build entire pages solely with Grid quickly becomes unwieldy when you need precise control over individual item placement or alignment. Furthermore, relying entirely on Grid's implicit sizing can make it harder to predictably manage spacing and padding across different screen sizes, necessitating more complex overrides than a well-crafted Flexbox setup might require.
When migrating from an older layout system (often based heavily on floats) to either Grid or Flexbox, the most significant challenge isn't necessarily the technical implementation itself; it's often the legacy CSS. Attempting to directly translate float-based layouts into Grid or Flexbox can result in a tangled mess of overrides and hacks that are difficult to maintain and debug. A more effective strategy involves refactoring the core layout logic, stripping away unnecessary floats entirely, and then strategically introducing either Grid or Flexbox – typically starting with the most complex areas where it provides the greatest benefit. Combining them intelligently—using Grid for overall page structure and Flexbox within grid items—is often a far superior approach than committing to one exclusively.
Frequently asked questions
What is the core difference between CSS Grid and Flexbox?
Flexbox is one-dimensional — it lays out items along a single axis (either a row or a column). CSS Grid is two-dimensional — it controls both rows and columns simultaneously. A good rule of thumb: use Flexbox for components, use Grid for page-level layouts.
Can I use CSS Grid and Flexbox together?
Absolutely — and you should. A common pattern is to use Grid for the overall page layout (header, sidebar, main, footer) and Flexbox inside each section to align the items within it. They are complementary, not competing.
Which has better browser support?
Both have excellent browser support in all modern browsers (Chrome, Firefox, Safari, Edge). Flexbox has slightly broader legacy support (including older IE 11 with prefixes). CSS Grid has full support in browsers released since 2017. For any project targeting modern browsers, both are safe to use.
Is Grid harder to learn than Flexbox?
Grid has a steeper initial learning curve because it introduces two axes simultaneously, plus concepts like grid areas, template columns/rows, and the fr unit. Flexbox is easier to get started with. Most developers find Flexbox intuitive within days; Grid takes a bit longer but pays off for complex layouts.
When should I use Flexbox for alignment?
Flexbox excels at centering things (align-items: center + justify-content: center is the classic one-liner to centre something vertically and horizontally), spacing items evenly with justify-content: space-between, and creating navigation bars or button groups.
What is the fr unit in CSS Grid?
fr stands for "fractional unit". It represents a fraction of the available space in the grid container. grid-template-columns: 1fr 2fr creates two columns where the second is twice as wide as the first. It replaces complex percentage calculations and automatically accounts for gaps.