CSS Grid vs. Flexbox: When to Use Each Layout
Use Flexbox to arrange items along one axis and Grid to coordinate rows and columns. See how to choose, combine them, and handle responsive layouts.
Short answer: Use Flexbox when items need to be arranged and distributed along one axis at a time: a row or a column. Use CSS Grid when rows and columns need to be coordinated together. Combine them when a page needs a two-dimensional structure and a component inside it needs a one-dimensional arrangement.
The key distinction is the layout problem, not the size of the component. A toolbar can use Grid if its tracks need coordination, and a large page region can use Flexbox if its contents flow along one axis. Both systems can wrap and respond to available space, but they give you different controls.
1. The core difference
Flexbox is a one-dimensional layout model: it lays out items in a row or a column. Grid is a two-dimensional layout model: it coordinates rows and columns at the same time. This is the central distinction described in MDN’s comparison of Grid with other layout methods and the CSS Grid specification.
| Question | Flexbox | Grid |
|---|---|---|
| What is the main constraint? | One axis: row or column. | Rows and columns together. |
| How do items get sized? | Often from their content, then grown, shrunk, or distributed along the main axis. | Often from container-defined tracks that items occupy; tracks can also respond to content. |
| What happens when items wrap? | Each line is laid out independently; items on separate lines do not automatically share column widths. | Items can occupy shared tracks, so columns can align across rows. |
| Where is placement controlled? | Primarily by flow direction, order, and alignment along the main and cross axes. | By tracks, lines, areas, placement, and spanning. |
These are useful tendencies, not rigid rules. Either system can express some of the same layouts. Choose the model that matches the relationships the design needs.
2. When to use Flexbox
Choose Flexbox when the items should follow one direction and share or distribute space along that direction. The MDN Flexbox guide describes it as a one-dimensional model with alignment and space-distribution controls.
- Navigation links arranged in a row.
- A toolbar with controls that should stay together or wrap when space is tight.
- A vertical stack of buttons, fields, or content blocks.
- A component whose items should grow or shrink based on available space and their content.
- A group where wrapped lines may distribute items independently.
Runnable example: flexible toolbar
<nav class="toolbar" aria-label="Primary navigation">
<a class="brand" href="/">Northstar</a>
<div class="toolbar-links">
<a href="/docs">Docs</a>
<a href="/guides">Guides</a>
<a href="/about">About</a>
</div>
<a class="toolbar-action" href="/start">Get started</a>
</nav>
<style>
* { box-sizing: border-box; }
.toolbar {
display: flex;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
padding: 1rem;
border-bottom: 1px solid #ddd;
}
.brand { font-weight: 700; margin-right: auto; }
.toolbar-links { display: flex; gap: 1rem; flex-wrap: wrap; }
.toolbar a { color: #183153; text-decoration: none; }
.toolbar-action { padding: .55rem .8rem; background: #eaf1ff; border-radius: .4rem; }
</style>
The outer flex container arranges the brand, link group, and action in one main direction. The nested flex container arranges the links in a row of its own. flex-wrap allows items to move to another line when needed; it does not make separate lines share item widths.
3. When to use Grid
Choose Grid when the relationship between rows and columns matters, or when items need explicit placement, named areas, spanning, or deliberate overlap.
- A page shell with coordinated header, sidebar, main content, and footer regions.
- A dashboard with panels aligned in shared columns and rows.
- A card collection where cards on different rows need consistent column alignment.
- A gallery whose items span multiple tracks.
- A repeated Flexbox layout accumulating width rules just to line up items across wrapped rows.
Runnable example: responsive card grid
<section class="cards" aria-label="Guides">
<article class="card"><h2>Layout basics</h2><p>Understand the building blocks.</p></article>
<article class="card"><h2>Responsive design</h2><p>Adapt tracks to the space available.</p></article>
<article class="card"><h2>Accessibility</h2><p>Keep source order meaningful.</p></article>
<article class="card"><h2>Components</h2><p>Choose layout rules that fit the content.</p></article>
</section>
<style>
* { box-sizing: border-box; }
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
gap: 1rem;
}
.card { padding: 1rem; border: 1px solid #ccd5e0; border-radius: .5rem; }
.card h2 { margin-top: 0; }
</style>
repeat() repeats the track pattern, auto-fit fits as many tracks as the available space allows, and minmax() sets a lower and upper size. The inner min(100%, 15rem) prevents a minimum track from overflowing a container narrower than that minimum. Grid adapts the number and size of tracks without a breakpoint for every screen width.
4. A practical decision guide
| Use case | Start with | Reason |
|---|---|---|
| Navigation or toolbar | Flexbox | Items flow and align along a primary direction. |
| Vertical stack of controls | Flexbox | The items share a column and need spacing or alignment. |
| Cards with independent row wrapping | Flexbox or Grid | Flexbox works if rows may size independently; Grid is clearer if columns must align. |
| Dashboard or page shell | Grid | Regions relate across rows and columns. |
| Items spanning columns or rows | Grid | Track placement and spanning are part of the design. |
| Wrapped Flexbox rows repeatedly need matching widths | Grid | Shared columns are the layout requirement. |
Ask: “Do these items need to line up with items in another row?” If yes, Grid is usually the direct choice. If they need to flow in one direction and share space along that direction, start with Flexbox.
5. How wrapping and sizing differ
Flexbox can wrap with flex-wrap: wrap. Each resulting flex line distributes its items separately. For example, if the final row of a card collection contains only two cards, those cards may grow or distribute differently from cards on the preceding line. That is appropriate when each line is an independent group. It is less suitable when every card must sit in the same column as the cards above it.
Grid defines tracks for the container. Items placed in those tracks can align across rows, and track sizing can combine fixed values, fractions, minimums, maximums, and content-based sizing. Grid is not inherently fixed-width: track definitions such as minmax() and repetition with auto-fit or auto-fill can adapt to available space.
Flexbox is not simply “content-sized” and Grid is not simply “fixed tracks.” Flex items have grow, shrink, and basis behavior; Grid tracks can size to content. The useful distinction is which relationship should drive the layout: item flow along one axis, or coordinated tracks in two dimensions.
6. Responsive layouts with either system
Both systems respond to available space. Flexbox can shrink, grow, and wrap items. Grid can change track counts and sizes, and media queries can change placement when the design needs a different structure. Base breakpoints on the point where the content or layout becomes strained, rather than targeting every device model. See MDN’s responsive design and media query guide.
Grid with a deliberate breakpoint
.page {
display: grid;
grid-template-columns: 16rem minmax(0, 1fr);
grid-template-areas: "sidebar main";
gap: 1.5rem;
}
.sidebar { grid-area: sidebar; }
.main { grid-area: main; min-width: 0; }
@media (max-width: 48rem) {
.page {
grid-template-columns: minmax(0, 1fr);
grid-template-areas:
"main"
"sidebar";
}
}
The example changes the page from two columns to one when the available width is no longer suitable for the sidebar and main content side by side. Choose an actual breakpoint based on the content and design.
Flexbox that wraps without a breakpoint
.actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
}
.actions > * { flex: 0 1 auto; }
.actions .primary { flex: 1 1 12rem; }
Use a media query when the composition must change, not merely because a particular device has a certain label. Test long labels, translated text, zoom, and narrow containers in addition to common viewport widths.
7. Use Grid and Flexbox together
There is no need to choose one layout system for an entire page. A common structure is Grid for the page’s coordinated regions and Flexbox inside a region for controls or navigation.
<div class="dashboard">
<header class="dashboard-header">
<strong>Operations</strong>
<div class="header-actions">
<button>Refresh</button>
<button>Export</button>
</div>
</header>
<aside>Sidebar</aside>
<main>Dashboard content</main>
</div>
<style>
.dashboard {
display: grid;
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: "header header" "sidebar main";
gap: 1rem;
}
.dashboard-header {
grid-area: header;
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.header-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.dashboard aside { grid-area: sidebar; }
.dashboard main { grid-area: main; min-width: 0; }
@media (max-width: 48rem) {
.dashboard {
grid-template-columns: minmax(0, 1fr);
grid-template-areas: "header" "main" "sidebar";
}
}
</style>
Use semantic source order that still makes sense if CSS does not load or a user navigates by assistive technology. Visual reordering with Grid placement or Flexbox order does not change the underlying reading or keyboard order.
8. Common layout problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Cards on separate flex lines do not align in columns | Flex lines size independently. | Use Grid when rows need shared columns. |
| A grid child forces the whole page wider than the viewport | A track or item’s automatic minimum size is larger than the available space. | Use minmax(0, 1fr) for a flexible track and, where needed, min-width: 0 on the grid item. Handle overflowing content separately. |
| Flex items overflow instead of shrinking | Content or an item’s minimum size prevents shrinking. | Check long unbreakable strings, intrinsic media sizes, and minimum widths. Add min-width: 0 when the item should be allowed to shrink, and set an appropriate wrapping or overflow rule for the content. |
| Grid columns are unexpectedly unequal | Track definitions or intrinsic content are affecting sizing. | Specify the intended track sizing explicitly, for example repeat(3, minmax(0, 1fr)), and inspect long content. |
| Items appear in a surprising visual order | Explicit placement, order, or auto-placement differs from source order. |
Keep markup in a meaningful order and use visual reordering only when it does not harm reading or keyboard navigation. |
| A responsive card grid has a single narrow overflow | The minimum track size exceeds the container width. | Use a minimum that can contract, such as minmax(min(100%, 15rem), 1fr). |
Flexbox gap does not appear in a required older browser |
Support for a particular feature can differ from support for the layout system generally. | Check the exact browser and feature requirements; use margins or another suitable fallback if the required audience needs it. |
9. Browser support and compatibility
Can I Use’s live tables displayed estimated global usage support of 96.89% for CSS Grid Layout Level 1 and 97.26% for Flexbox when accessed on October 3, 2026. These are changing aggregate estimates, not guarantees for your audience or every subfeature. The tables also distinguish full from partial support and show limitations in older browsers, including Internet Explorer. Review the precise feature and browser versions your project supports using the current Grid support table and Flexbox support table.
Do not infer that every newer Grid or Flexbox feature has identical support just because the core layout system is broadly available. If legacy browsers are in scope, decide which feature needs a fallback and check that feature specifically. A simpler block or flex layout may be a useful fallback for a Grid-enhanced design, depending on the page’s requirements.
10. Performance, reliability, and cost
For ordinary page layouts, choose Grid or Flexbox based on the layout relationships and maintainability. This comparison provides no benchmark showing one system is universally faster. Avoid unnecessary complexity: if the layout is one row, a full two-dimensional placement scheme may be harder to maintain; if columns must align across rows, repeated Flexbox width workarounds are harder to reason about than shared Grid tracks.
Reliability comes from matching the layout model to the content, keeping meaningful source order, allowing for long and translated content, and checking the specific browser features your audience requires. Both layout systems are built into CSS; there is no separate library or service cost to use them.
11. See the layout in a real browser
When a layout behaves differently than expected, inspect the actual page at the viewport sizes and content lengths that matter to your users. A screenshot can help review overflow, wrapping, track alignment, and responsive changes. ScreenshotNeo is a website screenshot API and MCP server from ScreenshotNeo; this CSS article’s examples do not require it, but it can capture a page for visual review. Its API accepts a URL and returns an image or PDF.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation for request options. Replace the example URL with a page you are authorized to capture. Keep the access key out of public client-side code and source control.
Or skip the browser setup
Cookie banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. The MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Every feature is on every plan.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Sign up for 1,000 free screenshots a month, with no card required.
12. FAQ
Can I use Grid and Flexbox in the same component?
Yes. A container can use Grid while one of its children uses Flexbox, or the other way around. Apply each layout model to the relationship it needs to control.
Should I replace every Flexbox layout with Grid?
No. Keep Flexbox when one-axis flow and distribution express the design clearly. Use Grid when the design depends on coordinated tracks or placement.
Is Flexbox only for small components and Grid only for page layouts?
No. Component size does not determine the right choice. The number of coordinated dimensions and the sizing behavior do.
Can Grid make a responsive layout without media queries?
Often, track functions such as repeat(), auto-fit, and minmax() can adapt a layout to available space. Use media queries when the composition itself needs to change.


