Flexbox and CSS Grid are two modern CSS layout modules. Both solve layout problems, but they work in different ways. Understanding their differences helps you choose the right tool for each task and write more predictable, maintainable code.
One-dimensional vs. two-dimensional
The main conceptual difference is that Flexbox is a one-dimensional system (a row or column), while Grid is two-dimensional (rows and columns at the same time).
Flexbox: one axis at a time
Flexbox arranges items along the main axis. With flex-wrap: wrap, items wrap, but each row is a separate flex container. Alignment between rows is controlled by align-content, but there is no relationship between items in different rows.
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.flex-item {
flex: 1 1 200px;
}Items grow to 200px and then wrap. The width of the resulting columns depends on how many items are in each row, so the columns may be uneven.
Grid: rows and columns
Grid defines an explicit grid: the number and sizes of columns and rows. Items are placed in cells, and alignment on both axes is controlled independently.
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}Each column has a minimum width of 200px and a maximum of 1fr. The grid remains predictable regardless of the number of items.
Comparison table
| Criterion | Flexbox | CSS Grid |
|---|---|---|
| Dimensions | One-dimensional (row or column) | Two-dimensional (rows and columns) |
| Control | Container + items | Mostly the container |
| Sizing | Flexible, content-based | Explicit or implicit tracks |
| Alignment | Along the main and cross axes | Independently on both axes |
| Nesting | Often used | Less necessary |
| Reverse order | flex-direction: row-reverse | direction: rtl or order |
When to choose Flexbox
UI components
Icon buttons, navigation menus, headers, and footers are typical one-dimensional layouts:
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}Centering
Centering vertically and horizontally is a classic use case for Flexbox:
.centered {
display: flex;
justify-content: center;
align-items: center;
}For more centering patterns, see CSS centering with Flexbox: all the methods.
Distributing space in one direction
When you need to distribute items evenly in a row or column:
.toolbar {
display: flex;
justify-content: space-between;
}
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}Content with a variable number of items
Lists, tags, and chips can have an unknown number of items, so flexible behavior is important:
.tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}When to choose CSS Grid
Card grids and galleries
Product catalogs, image galleries, and news feeds are classic two-dimensional grids:
.catalog {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}Complex page layouts
Layouts with a header, sidebar, main content, and footer, where alignment across rows and columns is needed:
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}Asymmetric layouts
When items span different numbers of cells:
.masonry {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.item-featured {
grid-column: span 2;
grid-row: span 2;
}Precise positioning
When you need control over the placement of each item:
.dashboard {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto auto;
gap: 1rem;
}
.widget-a { grid-column: 1; grid-row: 1; }
.widget-b { grid-column: 2 / 4; grid-row: 1; }
.widget-c { grid-column: 1 / 4; grid-row: 2; }Combining Flexbox and Grid
Often, the best solution is a combination: Grid for the overall structure and Flexbox for internal components.
.page {
display: grid;
grid-template-columns: 250px 1fr;
min-height: 100vh;
}
.sidebar {
display: flex;
flex-direction: column;
gap: 1rem;
}
.main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
align-content: start;
}Tools for experimenting
For quick Flexbox prototyping, use Flexbox Playground. For Grid, use the CSS Grid Generator on rechecker.ru. Both tools let you adjust properties visually and see the result immediately.
Performance
Browsers process both modules efficiently. Grid can be slightly more expensive for very large grids (hundreds of cells), but the difference is unnoticeable in typical use cases. Choose based on the layout semantics, not micro-optimizations.
Browser support
Flexbox has broader support, including IE10+. Grid is supported in all modern browsers, but is not supported in IE10-11. For projects that need to support older versions of IE, use Flexbox or fallback layouts.
Recommendations for choosing
- Ask yourself: is this a row/column or a grid? For a row/column, use Flexbox; for a grid, use Grid.
- Do you need alignment on both axes? If so, Grid makes this easier.
- Is the number of items fixed or variable? For a variable number of items with flexible wrapping, Flexbox is often a good fit. For a fixed grid, use Grid.
- Is the layout asymmetric? For items of different sizes or spanning, use Grid.
Example: one layout, two approaches
Consider a gallery of 6 cards. With Flexbox:
.flex-gallery {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.flex-gallery .card {
flex: 1 1 calc(33.333% - 1rem);
min-width: 200px;
}The problem: with 4 items in the last row, two will remain, and each will stretch to 50%. The grid appears to “jump.”
With Grid:
.grid-gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}Each item occupies exactly one cell. All cells are the same size, so the behavior is predictable.
Example: navigation
Flexbox is a more logical choice for navigation: it is a one-dimensional row that needs alignment:
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-links {
display: flex;
gap: 2rem;
}Grid is excessive here: only one axis is needed, and Flexbox makes alignment along the cross axis (vertical centering) simpler.
Migrating from Flexbox to Grid
If a Flexbox layout no longer meets your needs (for example, if you need aligned columns when the number of items varies), migrating is usually straightforward:
/* Было */
.flex {
display: flex;
flex-wrap: wrap;
}
.flex > * { flex: 1 1 300px; }
/* Стало */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}The reverse migration (Grid → Flexbox) is harder if you used grid-area, grid-column/grid-row, or asymmetric layouts.
Further reading
For a detailed guide to Flexbox, see CSS Flexbox: a complete guide with examples. For a complete overview of CSS Grid, see CSS Grid: a complete guide to grids.
Nested layouts
Flexbox is often used inside Grid cells:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.grid > * {
display: flex;
flex-direction: column;
gap: 0.5rem;
}Conversely, Grid can be used inside a Flexbox item for grid-based alignment.
Performance
Both modules are efficient. With thousands of items, delays are possible. For long lists, use virtualization (rendering only the visible items).
Learning
Flexbox is easier to start with: it has fewer properties and is more intuitive for one-dimensional tasks. Grid has a more complex model, but offers more control for grids. It is recommended to learn both.