- CSS
- Frontend
- Design
CSS Grid vs Flexbox: When to Use Which
When to use CSS Grid vs Flexbox: one- vs two-dimensional layout, a combined app layout example, and responsive grids with minmax().
Use Flexbox when you are laying out items in one direction, a single row or column, and want their content to influence their sizes, as in a navigation bar or a button with an icon. Use CSS Grid when you need to control rows and columns together, as in a page layout, dashboard or image gallery. Most real pages use both: Grid for the overall structure and Flexbox for the components inside it.
Key takeaways
- Flexbox is one-dimensional and works from the content out; Grid is two-dimensional and works from the layout in.
- Choose Flexbox for navbars, toolbars, centering and the inside of small components.
- Choose Grid for page layouts, card galleries, dashboards and anything that must line up in both directions.
repeat(auto-fit, minmax(200px, 1fr))creates a responsive grid without media queries.- Grid items can be placed in the same cells, so overlapping content doesn't require absolute positioning.
Grid or Flexbox: Do you have to choose?
For years, developers hacked layouts together with float, clear and position: absolute. Then came Flexbox, which made alignment easy. Then came CSS Grid, which confused a lot of us at first.
A question beginners often ask is: "Should I use Grid or Flexbox?" The experienced answer is: use both.
They are not competitors; they are teammates designed to solve different problems.
What is the core difference?
MDN frames the choice in two ways: flexbox is for one-dimensional layout and grid for two-dimensional layout, and flexbox works from the content out while grid works from the layout in (MDN: relationship of grid to other layout methods).
- Flexbox is content-first and one-dimensional. Use it when you want items to arrange themselves along a line (a row or a column) based on their size. Even with
flex-wrap: wrap, each new line is laid out independently, so items on different lines don't line up into columns. - CSS Grid is layout-first and two-dimensional. Use it when you want to define a structure of rows and columns and place content into it.
When should you use Flexbox?
Think of Flexbox as a necklace string. You thread beads (items) onto it. You can slide them to the start or end, or space them out, but they essentially live on a single line.
Best use cases for Flexbox
- Navigation bars: A logo on the left and links on the right. Perfect for
justify-content: space-between. - Buttons: Centering an icon and a text label inside a button.
- Form rows: An input field next to a "Submit" button.
- Card internals: Stacking and aligning the title, description and "Read more" link inside a card.
Flexbox code pattern
/* The container */
.navbar {
display: flex; /* Activate Flexbox */
justify-content: space-between; /* Alignment along the row (horizontal) */
align-items: center; /* Alignment across the row (vertical) */
}
When should you use CSS Grid?
Think of CSS Grid as a chessboard. You define the board first (for example, 8×8 squares), and then place pieces (content) onto specific squares.
Best use cases for Grid
- Page layouts: Defining the header, sidebar, main content and footer.
- Image galleries: Keeping a consistent set of columns regardless of individual image sizes.
- Dashboards: Arranging widgets where item A spans two columns and item B spans two rows.
- Layered content: Placing several items in the same grid cell or area to stack them without
position: absolute.
Grid code pattern
/* The container */
.dashboard-layout {
display: grid;
/* 3 columns: a 250px sidebar, a flexible main area, a 300px side panel */
grid-template-columns: 250px 1fr 300px;
/* 3 rows: header and footer sized to their content, the middle row takes the rest */
grid-template-rows: auto 1fr auto;
gap: 20px; /* Space between rows and columns */
}
The fr unit represents a share of the free space left in the grid container, so 1fr here means "whatever width is left after the fixed columns and gaps."
How do Grid and Flexbox work together?
Let's build a classic app layout using each technology where it shines: Grid for the page structure, Flexbox for the header's contents.
1. The macro layout (Grid)
We want a header across the top, a sidebar and a main content area.
2. The micro layout (Flexbox)
Inside the header, we have a logo and navigation links. We don't need a grid for that; we just need them in a row.
Here is the complete example. Paste it into the HTML, CSS & JavaScript editor and resize the preview to see how it behaves:
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
/* 1. Macro layout: Grid */
.app-container {
display: grid;
height: 100vh;
grid-template-areas:
"header header"
"sidebar main";
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
}
.sidebar { grid-area: sidebar; background: #f3f4f6; padding: 1rem; }
.main { grid-area: main; padding: 1rem; }
/* 2. Micro layout: Flexbox inside the header */
.header-nav {
grid-area: header;
display: flex; /* Switch to Flexbox */
align-items: center;
gap: 1rem;
padding: 0 1rem;
border-bottom: 1px solid #ddd;
}
</style>
<div class="app-container">
<header class="header-nav">
<strong>WebFiddle</strong>
<a href="#">Docs</a>
<a href="#">Blog</a>
</header>
<aside class="sidebar">Sidebar</aside>
<main class="main">Main content</main>
</div>
Notice that .header-nav is both a grid item (placed with grid-area: header) and a flex container for its own children. Nesting the two layout systems like this is normal and expected.
How does minmax() make a grid responsive?
One of the most useful Grid features is the minmax() function. Combined with repeat() and auto-fit, it creates responsive columns without media queries (MDN: minmax()).
.gallery {
display: grid;
/* As many columns as fit, each at least 200px wide, sharing any leftover space */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
As the container narrows, the browser fits fewer 200px-minimum columns and wraps items onto new rows, down to a single column. That one declaration replaces the set of breakpoint-specific media queries you would otherwise write. For a longer walkthrough of these functions, see web.dev's Learn CSS module on grid.
Summary
| Feature | Flexbox | CSS Grid |
|---|---|---|
| Dimensions | 1D (a row OR a column) | 2D (rows AND columns) |
| Mental model | Content out (items influence their size) | Layout in (items are placed into tracks) |
| Best for | Components, navbars, alignment | Page structure, galleries, complex layouts |
| Overlap | Awkward (negative margins or absolute positioning) | Built in (items can share cells) |
Rule of thumb: Start with Grid for the main page structure. Switch to Flexbox as soon as you are inside a specific component, like a card or navbar.
To brush up on the Flexbox properties used here, read CSS basics: box model, selectors and Flexbox, and to see how padding, borders and margins add to the size of each grid or flex item, read the CSS box model explained. To choose the right elements for those layout regions, see semantic HTML for SEO and accessibility.
Frequently asked questions
Is CSS Grid better than Flexbox?
Neither is better overall, because they solve different problems. Flexbox is designed for arranging items along a single row or column, while Grid controls rows and columns at the same time. Most layouts combine them, using Grid for the page structure and Flexbox for aligning content inside components such as headers and cards.
Can Flexbox create a grid layout?
Partly. With flex-wrap and fixed item widths, you can make items flow into rows that look like a grid. However, each flex line is sized independently, so items in different rows will not line up into true columns when their content varies. When alignment in both directions matters, CSS Grid is the simpler choice.
How do I center an element with Flexbox or Grid?
With Flexbox, give the parent display: flex, justify-content: center and align-items: center. With Grid, give the parent display: grid and place-items: center. Both approaches center the child horizontally and vertically, as long as the parent is taller than the child, for example by setting a height or min-height.
What is the difference between auto-fit and auto-fill?
Both keywords create as many grid columns as fit in the container. The difference appears when there are fewer items than available columns. With auto-fill, the empty column tracks are kept, so items leave space for them. With auto-fit, empty tracks collapse to zero, letting the existing items stretch across the whole row.
WebFiddle