Flexbox vs Grid — when to use each
Flexbox and CSS Grid are both layout tools, but they solve different problems. Flexbox excels at one-dimensional layouts (rows or columns), while Grid is powerful for two-dimensional layouts (rows AND columns). Understanding their strengths helps you choose the right tool for each layout challenge.
Key differences
Aspect | Flexbox | Grid |
|---|---|---|
Dimensions | One-dimensional (row OR column) | Two-dimensional (row AND column) |
Direction | Row or column, one axis | Both axes simultaneously |
Items | Linear arrangement | Grid of cells |
Best for | Navigation, toolbars, components | Page layouts, dashboards |
Content | Content-based sizing by default | Container-based sizing |
Alignment | main-axis & cross-axis | Rows and columns |
CSS
<!-- Flexbox: one dimension at a time -->
.navbar {
display: flex;
gap: 20px;
justify-content: space-between;
align-items: center;
}
<!-- Controls horizontal arrangement -->
<!-- Vertical alignment is secondary (cross-axis) -->
.sidebar {
display: flex;
flex-direction: column;
gap: 10px;
}
<!-- Controls vertical arrangement -->
<!-- Horizontal alignment is secondary (cross-axis) -->
/* Grid: two dimensions together -->
.dashboard {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns -->
grid-template-rows: auto 1fr auto; /* 3 rows -->
gap: 20px;
}
<!-- Controls BOTH columns and rows -->
<!-- Items placed in specific cells -->
/* Conceptual difference -->
.flex-row {
display: flex; /* items in a line -->
}
<!-- [Item] [Item] [Item] (all in one row) -->
.flex-column {
display: flex;
flex-direction: column;
}
<!-- [Item] -->
<!-- [Item] -->
<!-- [Item] (all in one column) -->
.grid-layout {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3x3 grid -->
grid-template-rows: 1fr 1fr 1fr;
}
<!-- [Item] [Item] [Item] -->
<!-- [Item] [Item] [Item] (items in cells) -->
<!-- [Item] [Item] [Item] -->When to use Flexbox
CSS
<!-- Use flexbox for: -->
/* 1. Navigation and menus (horizontal layout) -->
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
<!-- Logo, nav items, buttons all in a row -->
/* 2. Toolbars and button groups -->
.toolbar {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.button {
flex: 0 0 auto;
}
<!-- Buttons arranged, wrap to new line if needed -->
/* 3. Cards and components -->
.card {
display: flex;
flex-direction: column;
gap: 15px;
}
.card-header {
flex: 0 0 auto;
}
.card-content {
flex: 1;
}
.card-footer {
flex: 0 0 auto;
}
<!-- Card structure: vertical arrangement -->
/* 4. Flexible spacing and alignment -->
.hero {
display: flex;
justify-content: center;
align-items: center;
height: 400px;
}
<!-- Content centered both ways -->
/* 5. Responsive wrapping -->
.gallery {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.item {
flex: 1 1 200px;
}
<!-- Items wrap naturally based on space -->
/* 6. Sidebar + content (two-column) -->
.layout {
display: flex;
gap: 20px;
}
.sidebar {
flex: 0 0 250px;
}
.content {
flex: 1;
}
<!-- Simple side-by-side layout -->When to use Grid
CSS
<!-- Use grid for: -->
/* 1. Page layouts (header, sidebar, content, footer) -->
.page {
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-rows: auto 1fr auto;
gap: 20px;
min-height: 100vh;
}
.header { grid-column: 1 / -1; }
.sidebar { grid-row: 2; }
.content { grid-row: 2; }
.footer { grid-column: 1 / -1; }
<!-- Complex layout with multiple rows/columns -->
/* 2. Dashboards (many cells) -->
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 20px;
}
.card {
grid-column: span 1; /* 1 cell wide -->
}
.feature {
grid-column: span 2; /* 2 cells wide -->
}
<!-- Widgets in specific grid positions -->
/* 3. Image grids and galleries -->
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.image {
grid-column: auto;
}
.featured {
grid-column: span 2;
}
<!-- Images in grid with some spanning -->
/* 4. Magazine-style layouts -->
.magazine {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 20px;
}
.article-main {
grid-column: span 8;
}
.sidebar {
grid-column: span 4;
}
<!-- Asymmetric layout -->
/* 5. Form layouts with aligned labels -->
.form {
display: grid;
grid-template-columns: 200px 1fr;
gap: 20px;
}
.label {
grid-column: 1;
}
input {
grid-column: 2;
}
<!-- Perfectly aligned columns -->
/* 6. Data tables and spreadsheets -->
.table {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 1px;
}
.cell {
padding: 10px;
}
<!-- Uniform grid cells -->Direct comparison: common layouts
CSS
<!-- Two-column layout -->
/* Flexbox approach -->
.flex-layout {
display: flex;
gap: 20px;
}
.flex-sidebar {
flex: 0 0 250px;
}
.flex-content {
flex: 1;
}
<!-- Simple and semantic -->
/* Grid approach -->
.grid-layout {
display: grid;
grid-template-columns: 250px 1fr;
gap: 20px;
}
.grid-sidebar {
grid-column: 1;
}
.grid-content {
grid-column: 2;
}
<!-- More explicit but more code -->
/* Three-column layout -->
/* Flexbox with equal columns -->
.flex-three {
display: flex;
gap: 20px;
}
.flex-col {
flex: 1 1 0;
}
<!-- Simple: flex: 1 makes equal -->
/* Grid with equal columns -->
.grid-three {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
<!-- Also clear: three equal 1fr columns -->
/* Navbar + main + footer -->
/* Flexbox vertical layout -->
.flex-page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.flex-header {
flex: 0 0 60px;
}
.flex-main {
flex: 1;
}
.flex-footer {
flex: 0 0 40px;
}
<!-- Semantic and straightforward -->
/* Grid 2D layout -->
.grid-page {
display: grid;
grid-template-rows: 60px 1fr 40px;
min-height: 100vh;
}
.grid-header {
grid-row: 1;
}
.grid-main {
grid-row: 2;
}
.grid-footer {
grid-row: 3;
}
<!-- More explicit grid structure -->Hybrid approach: Flexbox + Grid
CSS
<!-- Use both together for complex layouts -->
<!-- Page structure: Grid -->
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 40px;
min-height: 100vh;
gap: 20px;
}
.header { grid-column: 1 / -1; }
.sidebar { grid-row: 2; }
.content { grid-row: 2; }
.footer { grid-column: 1 / -1; }
<!-- Header structure: Flexbox -->
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo { flex: 0 0 auto; }
.nav { flex: 1; justify-content: center; }
.actions { flex: 0 0 auto; }
<!-- Content structure: Grid -->
.content {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.card {
display: flex; /* Flexbox for card internals -->
flex-direction: column;
gap: 10px;
}
.card-header { flex: 0 0 auto; }
.card-body { flex: 1; }
.card-footer { flex: 0 0 auto; }
<!-- Grid for page + card grid, Flexbox for components -->
/* Decision tree: -->
/* Is it one row OR one column? --> Flexbox -->
/* Is it rows AND columns together? --> Grid -->
/* Is it complex with nested layouts? --> Both! -->Note
Flexbox is for one-dimensional layouts (navbar, sidebar, card internals). Grid is for two-dimensional layouts (page structure, dashboards, galleries). For complex layouts, use Grid for overall structure and Flexbox for component internals. They complement each other — you rarely need to choose just one.
Next
Master CSS Grid: [Grid Introduction](/css/grid-intro).