CSS Layout in 2026: Flexbox, Grid, and When to Use Each (2026)
Stop guessing with margins and floats. Here's how modern CSS layout actually works.
The Evolution
1990s: Table layouts (don't ask)
2000s: Float-based layouts (clearfix hacks everywhere)
2010s: Flexbox (one-dimensional layout savior)
2020s: Grid (two-dimensional layout done right)
2026: Flexbox + Grid + Container Queries = complete toolkit
Quick Decision Guide
Need to lay out items in ONE direction?
→ Use FLEXBOX (row or column)
Need to lay out items in TWO directions (rows AND columns)?
→ Use GRID
Need a component that adapts to its container size?
→ Use CONTAINER QUERIES + Grid/Flexbox
Simple centering?
→ Either works (Flexbox is shorter)
Flexbox Deep Dive
The Core Concept
/* Flexbox = one-dimensional layout */
/* Items flow in either a ROW or a COLUMN */
.container {
display: flex;
/* Main axis: horizontal by default */
/* Cross axis: perpendicular to main axis */
}
Direction & Wrapping
.container {
display: flex;
/* Main axis direction */
flex-direction: row; /* left → right (default) */
flex-direction: row-reverse; /* right → left */
flex-direction: column; /* top → bottom */
flex-direction: column-reverse;/* bottom → top */
/* Wrapping behavior */
flex-wrap: nowrap; /* single line, shrink if needed (default) */
flex-wrap: wrap; /* multi-line, flows to next line */
flex-wrap: wrap-reverse; /* wraps in reverse order */
}
/* Shorthand */
flex-flow: row wrap; /* direction + wrap together */
Alignment (This Is Where Most People Get Stuck)
.container {
display: flex;
/* MAIN AXIS alignment (justify) */
justify-content: flex-start; /* pack to start (default) */
justify-content: flex-end; /* pack to end */
justify-content: center; /* center horizontally */
justify-content: space-between; /* equal space BETWEEN items */
justify-content: space-around; /* equal space AROUND items */
justify-content: space-evenly; /* exactly equal space everywhere */
/* CROSS AXIS alignment (align) — controls the OTHER dimension */
align-items: stretch; /* stretch to fill (default) */
align-items: flex-start; /* align to cross-axis start */
align-items: flex-end; /* align to cross-axis end */
align-items: center; /* center vertically */
align-items: baseline; /* align text baselines */
}
/* Visual reference:
justify-content (main axis →):
┌─────────────────────────────┐
│ [item] [item] [item] │ space-between
│ [item] [item] [item] [item]│ space-evenly
│ [item] [item] │ center
align-items (cross axis ↓):
┌──┐
│ │ item flex-start
├──┤
│ │ item center
├──┤
│ │ item flex-end
└──┘
*/
Item-Level Control
.item {
/* How much can this item grow? */
flex-grow: 0; /* don't grow (default) */
flex-grow: 1; /* grow equally with siblings */
flex-grow: 2; /* grow 2x as much as flex-grow:1 siblings */
/* How much can this item shrink? */
flex-shrink: 1; /* shrink equally (default) */
flex-shrink: 0; /* never shrink (important for icons/buttons!) */
/* Base size before growing/shrinking */
flex-basis: auto; /* use content size (default) */
flex-basis: 200px; /* start at 200px */
flex-basis: 0; /* start at 0 (useful for equal-width items) */
/* Override container's align-items for this specific item */
align-self: center; /* this item centers itself */
align-self: flex-start; /* this item sticks to start */
}
/* Shorthand: grow | shrink | basis */
flex: 1; /* flex-grow: 1; flex-shrink: 1; flex-basis: 0% */
flex: 0 0 auto; /* don't grow, don't shrink, use content size */
flex: 1 1 200px; /* grow, shrink, start at 200px */
/* THE magic trick: equal-width children */
.equal-children > * {
flex: 1;
}
Real-World Flexbox Patterns
/* Pattern 1: Perfect centering (the #1 use case) */
.center-all {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Pattern 2: Navbar */
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
}
.navbar > .logo { flex-shrink: 0; }
.navbar > .nav-links { display: flex; gap: 1rem; }
/* Pattern 3: Card with sticky footer */
.card {
display: flex;
flex-direction: column;
}
.card-body { flex: 1; } /* Takes all available space */
.card-footer { /* normal size, stays at bottom */ }
/* Pattern 4: Media object (avatar + text) */
.media-object {
display: flex;
align-items: flex-start;
gap: 1rem;
}
.media-object > .avatar {
flex-shrink: 0; /* Avatar never squishes */
width: 48px;
height: 48px;
}
.media-object > .content { flex: 1; } /* Text takes rest */
/* Pattern 5: Form row */
.form-row {
display: flex;
gap: 1rem;
flex-wrap: wrap; /* Responsive: wraps on small screens */
}
.form-row > * {
flex: 1 1 200px; /* Min 200px, grow equally */
}
/* Pattern 6: Loading spinner overlay */
.loading-overlay {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.5);
}
CSS Grid Deep Dive
The Core Concept
/* Grid = two-dimensional layout */
/* Define rows AND columns explicitly */
.container {
display: grid;
/* Define columns */
grid-template-columns: 200px 1fr 200px;
/* Define rows */
grid-template-rows: auto 1fr auto;
/* Gap between cells */
gap: 1rem;
}
The fr Unit (Game Changer)
/* fr = "fraction of available space" */
.grid-3-equal {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* Three equal columns */
}
.grid-sidebar {
display: grid;
grid-template-columns: 250px 1fr; /* Fixed sidebar + fluid content */
}
.grid-complex {
display: grid;
grid-template-columns: 200px 1fr 300px; /* Left nav + content + right panel */
grid-template-rows: 60px 1fr 40px; /* Header + main + footer */
}
/* repeat() saves typing */
.grid-12 {
display: grid;
grid-template-columns: repeat(12, 1fr); /* 12-column grid system */
}
/* minmax() for responsive without media queries */
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* Automatically creates as many 250px+ columns as fit */
gap: 1rem;
}
Placing Items
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto auto;
gap: 1rem;
}
/* Method 1: Auto-placement (items flow in order) */
.item { /* just place them, they'll fill cells */ }
/* Method 2: Line-based placement */
.header {
grid-column: 1 / -1; /* From column 1 to last column */
grid-row: 1 / 2;
}
.sidebar {
grid-column: 1 / 2;
grid-row: 2 / 4; /* Spans rows 2 and 3 */
}
.main {
grid-column: 2 / -1;
grid-row: 2 / 3;
}
/* Method 3: Named areas (most readable!) */
.dashboard {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"sidebar footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Method 4: span keyword */
.featured {
grid-column: span 2; /* Spans 2 columns */
grid-row: span 2; /* Spans 2 rows */
}
Alignment in Grid
.container {
display: grid;
/* Align content within grid area */
justify-items: start; /* horizontal alignment inside cell */
align-items: start; /* vertical alignment inside cell */
/* Values: start, end, center, stretch */
/* Align entire grid tracks when smaller than container */
justify-content: center; /* center the whole grid */
align-content: center;
/* Per-item override */
.specific-item {
justify-self: end;
align-self: center;
}
}
Real-World Grid Patterns
/* Pattern 1: Holy Grail Layout */
.holy-grail {
display: grid;
grid-template:
"header header header" auto
"nav content aside" 1fr
"footer footer footer" auto
/ 200px 1fr 200px;
min-height: 100vh;
gap: 1rem;
}
/* Pattern 2: Card Grid (responsive) */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
/* No media queries needed! Cards reflow automatically */
/* Pattern 3: Dashboard */
.dashboard-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
.widget-wide { grid-column: span 2; }
.widget-tall { grid-row: span 2; }
/* Pattern 4: Image gallery (Masonry-like) */
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
gap: 0.5rem;
}
.gallery img:nth-child(5n+1) { grid-row: span 2; } /* Some images taller */
/* Pattern 5: Form layout */
.form-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 1rem;
align-items: center;
}
.form-grid label { text-align: right; }
.form-grid .full-width { grid-column: span 2; }
/* Pattern 6: Feature comparison table */
.comparison-table {
display: grid;
grid-template-columns: 2fr repeat(3, 1fr);
gap: 1px;
background: #e0e0e0; /* Gap color = border effect */
}
.comparison-table > * {
background: white;
padding: 1rem;
}
Container Queries (2026 Essential)
/* Media queries: style based on VIEWPORT size */
/* Container queries: style based on CONTAINER size */
/* Define a container */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Style based on container width, not viewport! */
@container card (min-width: 400px) {
.card-inner {
display: grid;
grid-template-columns: 200px 1fr;
}
}
@container card (min-width: 600px) {
.card-inner {
grid-template-columns: 250px 1fr 150px;
}
}
/* This means your component looks great ANYWHERE:
In a sidebar, in a modal, in a grid cell, in full page.
The component adapts to its own space! */
When to Use What
| Layout Need | Best Tool |
|---|---|
| Center one element | Flexbox (shorter) |
| Navigation bar | Flexbox |
| Card components | Flexbox (column) |
| Overall page layout | Grid |
| Dashboard with panels | Grid |
| Photo gallery | Grid |
| Form alignment | Grid (or Flexbox) |
| Sticky footer | Flexbox |
| Equal-height columns | Flexbox (align-items: stretch) |
| Complex overlapping | Grid (grid-area) |
| Component that adapts anywhere | Container Query + Grid/Flex |
Common Mistakes
/* ❌ Using margin: 0 auto for everything */
.center-old-school {
width: 80%;
margin: 0 auto; /* Only works with explicit width */
}
/* ✅ Modern centering */
.center-modern {
display: flex;
justify-content: center;
align-items: center;
}
/* ❌ Float-based layout */
.float-layout::after {
content: "";
clear: both;
display: table;
}
.left { float: left; }
.right { float: right; }
/* ✅ Don't use floats for layout in 2026 */
.flex-layout { display: flex; }
.grid-layout { display: grid; }
/* ❌ Fixed heights */
.sidebar { height: 500px; } /* Breaks on any content change */
/* ✅ Let content determine height */
.sidebar {
/* Just let it flow naturally */
overflow-y: auto; /* Scroll only if needed */
}
/* ❌ Negative margins for positioning */
.bad-positioning { margin-top: -50px; }
/* ✅ Use proper layout tools */
.good-positioning {
display: grid;
grid-row: 1 / 3; /* Overlap properly */
}
Are you team Flexbox, team Grid, or "it depends"?
Follow @armorbreak for more practical web dev guides.
Top comments (0)