CSS Flexbox vs Grid: When to Use Which
- Learn when to use CSS Flexbox vs CSS Grid.
- Covers flexbox vs grid at a glance.
- How Flexbox Works.
- How CSS Grid Works.
- Covers one dimension vs two dimensions.
Flexbox vs Grid at a Glance
CSS Flexbox and CSS Grid are both layout systems built into every modern browser. They solve different problems, and the best layouts use both. The short version: Flexbox handles one-dimensional layouts — a single row or a single column. Grid handles two-dimensional layouts — rows and columns simultaneously.
Neither is better than the other. They are complementary tools designed for different jobs. A navigation bar is a row of items — Flexbox. A dashboard with cards arranged in rows and columns — Grid. A card component where content stacks vertically — Flexbox. The entire page layout — Grid.
Understanding when to reach for each one eliminates guesswork and produces cleaner, more maintainable CSS. This guide breaks down both systems, compares them side by side, and gives you a practical decision framework.
How Flexbox Works
Flexbox — formally the Flexible Box Layout Module — distributes space along a single axis. You set a container to display: flex, and its direct children become flex items that flow along the main axis. By default, items arrange themselves in a horizontal row.
-webkit-backdrop-filter alongside backdrop-filter for Safari support. Without the prefix, the effect is invisible to roughly 25% of mobile users.The main axis is the direction items flow. The cross axis runs perpendicular to it. Most Flexbox properties — justify-content, flex-grow, flex-shrink, flex-basis — control behavior along the main axis. The align-items and align-self properties control the cross axis.
Flexbox excels at distributing variable amounts of space between items. A navigation bar where some links are short and some are long, a toolbar with buttons of different sizes, or a card footer where actions should be pushed to the right — these are Flexbox problems.
How CSS Grid Works
CSS Grid is a two-dimensional layout system. You define both rows and columns on a container, then place items into the resulting cells. Grid gives you explicit control over where content sits in both dimensions simultaneously.
backdrop-filter inside a position: fixed element can cause severe scroll performance issues. Test thoroughly on real iOS devices.The fundamental concepts are grid-template-columns and grid-template-rows for defining the structure, and grid-column/grid-row for placing items. The fr unit — a fraction of available space — is unique to Grid and makes proportional layouts simple.
Grid shines when you need items to align both horizontally and vertically. A photo gallery, a dashboard, a page layout with sidebar and main content, or any interface where items should snap to a consistent spatial framework.
One Dimension vs Two Dimensions
The most important distinction: Flexbox thinks in one direction at a time. Even when flex items wrap to multiple lines, each line is laid out independently. Items on line two have no relationship to items on line one.
Grid thinks in two directions simultaneously. A cell in row two, column three is explicitly related to the cells above and beside it. This means Grid can create layouts where content aligns across both axes — something Flexbox cannot do without additional markup.
This is not a weakness of Flexbox. It is a design feature. When you want items to flow naturally and take up whatever space they need, one-dimensional thinking is exactly right. When you want items to conform to a strict spatial grid, two-dimensional thinking is what you need.
When to Choose Flexbox
Use Flexbox when your layout is fundamentally a row or a column. Navigation bars, toolbars, button groups, card footers, form input rows, breadcrumbs, tag lists, and any component where items flow in a single direction.
Flexbox is also the right choice when items have intrinsic sizes that should be respected. A flex container distributes space based on the content inside each item. A short label next to a long label will naturally get different amounts of space — exactly what you want in a nav bar.
Another strong signal: when you need to push items apart. justify-content: space-between with Flexbox gives you a left-aligned item and a right-aligned item with space in the middle. This pattern appears in headers, card footers, and list rows throughout modern UI design.
When to Choose Grid
Use Grid when you need to control both rows and columns. Dashboards, image galleries, product listing pages, magazine-style layouts, and any interface where items should align on a consistent spatial framework.
Grid is also the right choice when you want items to be the same size regardless of their content. grid-template-columns: repeat(3, 1fr) gives you three equal columns. The content adapts to the container rather than the container adapting to the content — the opposite of Flexbox behavior.
Another strong signal: when you need items to span multiple rows or columns. A featured card that takes up two columns, a sidebar that spans the full height of the page — these are Grid problems. Grid makes it trivial to place items anywhere in the two-dimensional space.
Using Flexbox and Grid Together
The best layouts use both. A common pattern: Grid defines the overall page structure — header, sidebar, main content, footer. Inside each grid area, Flexbox handles component-level layouts — the navigation items in the header, the card content in the main area.
Think of Grid as the architect and Flexbox as the interior designer. Grid determines where the rooms go. Flexbox arranges the furniture inside each room. This separation of concerns produces CSS that is easier to read, maintain, and modify.
A practical example: a three-column card grid. The outer container uses display: grid with repeat(auto-fill, minmax(300px, 1fr)) to create responsive columns. Each card uses display: flex with flex-direction: column to stack its image, title, description, and footer vertically. The card footer uses Flexbox again to push the price left and the button right.
Common Layout Patterns
Holy Grail layout: header, footer, left sidebar, right sidebar, main content. This is a Grid problem. Define a 3-column, 3-row grid, then place each element with grid-area. The header and footer span all columns. The sidebars and main content share the middle row.
Card grid: equal-size cards that reflow responsively. Use Grid with auto-fill and minmax. The cards will form as many columns as the container allows at a minimum width, and grow to fill remaining space.
Centered content with max-width: a single column of content centered on the page. While this can be done with Grid (grid-template-columns: 1fr min(720px, 100%) 1fr), it is often simpler with margin: 0 auto and max-width — no layout system needed at all.
Alignment Deep Dive
Both Flexbox and Grid share the same alignment properties: justify-content, align-items, align-self, justify-self, and gap. The behavior is nearly identical, but the axes they apply to differ.
In Flexbox, justify-content works along the main axis (horizontal by default) and align-items works along the cross axis (vertical by default). In Grid, justify controls the inline axis (horizontal) and align controls the block axis (vertical). The place-items shorthand sets both at once.
The gap property works identically in both. It sets the space between items without affecting the space at the edges. This replaced the old margin-based spacing hacks and negative-margin workarounds that made layout code fragile.
Responsive Design Strategies
Flexbox responds naturally. When a flex container wraps, items flow to the next line based on their flex-basis. You rarely need media queries for simple Flexbox layouts — the content just reflows.
Grid's auto-fill and minmax functions create responsive layouts without media queries. grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) creates a grid that adjusts from one to four or more columns based on the available width. No breakpoints needed.
For more complex responsive changes — like switching from a sidebar layout to a stacked layout on mobile — media queries with Grid are straightforward. Change grid-template-columns from 250px 1fr to 1fr, and the sidebar stacks above the main content.
Performance Considerations
Both Flexbox and Grid are performant in all modern browsers. Layout calculations happen on the GPU. Benchmarks show negligible differences between the two for typical page layouts.
The main performance consideration is unnecessary nesting. Deeply nested flex containers — where every div has display: flex just to center one item — add layout complexity. Use Grid to flatten your markup when you find yourself nesting three or more flex containers.
Avoid layout thrashing by not reading layout properties (offsetHeight, getBoundingClientRect) immediately after changing styles. This is a general performance rule, not specific to Flexbox or Grid, but it becomes more impactful in complex layouts.
The Decision Framework
Ask yourself three questions. First: am I laying out items in one direction or two? If one direction, start with Flexbox. If two, start with Grid. Second: should items size themselves based on their content, or should they conform to a spatial framework? Content-driven sizing is Flexbox. Framework-driven sizing is Grid.
Third: do I need items to span multiple rows or columns? If yes, Grid. Flexbox has no concept of spanning — items can only grow or shrink along the main axis.
When in doubt, start with Flexbox. It handles more use cases with less code. Reach for Grid when you realize you need two-dimensional control, consistent column alignment, or item spanning. Most real-world layouts use both — Grid for the page, Flexbox for the components.
Use the Flexbox Playground to experiment with every Flexbox property. Drag items, toggle alignment, and copy the CSS.
⚡ Open Flexbox Playground