CSS Flexbox & Grid: The Layout Guide I Wish I Had (2026)
CSS layout used to be painful. Flexbox and Grid changed everything. Here's the practical guide that makes them click.
Flexbox: One-Dimensional Layout
/* The core concept: Flexbox manages layout in ONE direction (row or column)
Think of it as: "I have items, how do I arrange them in a line?" */
.container {
display: flex;
/* Main axis direction */
flex-direction: row; /* Left to right (default) */
/* flex-direction: row-reverse; */ /* Right to left */
/* flex-direction: column; */ /* Top to bottom */
/* flex-direction: column-reverse; */ /* Bottom to top */
/* Wrapping behavior */
flex-wrap: nowrap; /* Single line (default) */
/* flex-wrap: wrap; */ /* Multi-line when overflow */
/* flex-wrap: wrap-reverse; */ /* Wrap upwards */
/* Shorthand for direction + wrap */
flex-flow: row wrap;
/* Main axis alignment (how items spread along the main axis) */
justify-content: flex-start; /* Start (default) */
/* justify-content: flex-end; */ /* End */
/* justify-content: center; */ /* Centered */
/* justify-content: space-between; */ /* Space between items, no space at edges */
/* justify-content: space-around; */ /* Equal space around each item */
/* justify-content: space-evenly; */ /* Perfectly equal spacing */
/* Cross axis alignment (perpendicular to main axis) */
align-items: stretch; /* Stretch to fill (default) */
/* align-items: flex-start; */ /* Start of cross axis */
/* align-items: flex-end; */ /* End of cross axis */
/* align-items: center; */ /* Center of cross axis */
/* align-items: baseline; */ /* Text baseline alignment */
}
/* Item-level control */
.item {
/* How much this item can grow relative to others */
flex-grow: 0; /* Don't grow (default) */
/* flex-grow: 1; */ /* Grow equally with other growable items */
/* flex-grow: 2; */ /* Grow 2x more than flex-grow:1 items */
/* How much this item can shrink */
flex-shrink: 1; /* Shrink if needed (default) */
/* flex-shrink: 0; */ /* Never shrink (important for icons!) */
/* Base size before growing/shrinking */
flex-basis: auto; /* Auto or specific size */
/* flex-basis: 200px; */ /* Start at 200px */
/* Shorthand: grow | shrink | basis */
flex: 0 0 auto; /* Don't grow, don't shrink, auto size (= flex: none) */
flex: 1 1 auto; /* Grow, shrink, auto (= flex: auto) */
flex: 0 1 auto; /* Default value */
/* Override container's cross-axis alignment */
align-self: center; /* This item centers itself! */
/* Ordering (visual only, affects DOM order for accessibility) */
order: 0; /* Default */
order: -1; /* Appears BEFORE items with order 0 */
order: 1; /* Appears AFTER items with order 0 */
}
Common Flexbox Patterns
/* === Pattern 1: Perfect Centering === */
.center-all {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh; /* Full viewport height */
}
/* Works for ANY content size — no width/height needed on child! */
/* === Pattern 2: Navbar === */
.navbar {
display: flex;
justify-content: space-between; /* Logo left, links right */
align-items: center; /* Vertically centered */
padding: 0 2rem;
}
.nav-links {
display: flex;
gap: 2rem; /* Space between nav items (modern!) */
list-style: none;
}
/* === Pattern 3: Card Grid (with Flexbox) */
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1rem; /* Space between cards (replaces margin hacks!) */
}
.card {
flex: 1 1 300px; /* Min 300px, grow equally, can shrink */
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* Result: Responsive grid without media queries!
Narrow screen → 1 card per row
Medium → 2 cards
Wide → 3+ cards depending on space */
/* === Pattern 4: Sticky Footer === */
.page-wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main-content {
flex: 1; /* Push footer to bottom even with little content */
}
.footer {
padding: 1rem;
background: #333;
color: white;
}
/* === Pattern 5: Media Object (avatar + text) === */
.media-object {
display: flex;
align-items: flex-start; /* Top-align (not stretch!) */
gap: 1rem;
}
.media-avatar {
flex-shrink: 0; /* Avatar never squishes! */
width: 48px;
height: 48px;
border-radius: 50%;
}
.media-body {
flex: 1; /* Text takes remaining space */
min-width: 0; /* Allows text truncation to work */
}
.media-body h3 {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /* Truncate long titles */
}
CSS Grid: Two-Dimensional Layout
/* The core concept: Grid manages layout in TWO directions simultaneously
Think of it as: "I have a table-like structure, how do I place items?" */
.grid-container {
display: grid;
/* Define columns (the superpower!) */
grid-template-columns: 200px 1fr 200px; /* Fixed / fluid / Fixed */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* Responsive! */
grid-template-columns: 1fr 2fr 1fr; /* Ratio-based */
grid-template-columns: minmax(200px, 400px) 1fr; /* Range constraint */
/* Define rows */
grid-template-rows: auto 1fr auto; /* Header / Content / Footer */
grid-template-rows: masonry; /* Masonry layout (experimental but cool!) */
/* Gap between cells */
gap: 1rem; /* Uniform gap (replaces margin!) */
row-gap: 0.5rem;
column-gap: 1rem;
/* Place items within the grid */
justify-items: start; /* Horizontal alignment in cell */
/* justify-items: end | center | stretch (default) */
align-items: start; /* Vertical alignment in cell */
/* align-items: end | center | stretch (default) */
/* Entire grid placement (when grid is smaller than container) */
justify-content: center;
align-content: center;
}
/* Item placement (THE real power of Grid!) */
.grid-item {
/* Span across columns/rows */
grid-column: 1 / -1; /* From first to last column = full width */
grid-column: 1 / span 2; /* Start at col 1, span 2 cols */
grid-column: 2 / 4; /* From col 2 to col 4 */
grid-row: 1 / 3; /* Span rows 1-2 */
/* Shorthand */
grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
/* Named areas (readable layout definition!) */
grid-area: header;
}
/* Named Grid Areas — layout as ASCII art! */
.page-grid {
display: grid;
grid-template-columns: 250px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
gap: 1rem;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
When to Use Which?
┌─────────────────────┬──────────────────┬──────────────────┐
│ Scenario │ Use Flexbox │ Use Grid │
├─────────────────────┼──────────────────┼──────────────────┤
│ Navbar │ ✅ Yes │ ❌ No │
│ Center one item │ ✅ Yes (simpler) │ ✅ Yes │
│ Card components │ ✅ Yes │ ❌ No │
│ Full page layout │ ⚠️ Can work │ ✅ Better │
│ Dashboard/masonry │ ❌ Hard │ ✅ Yes │
│ Row of equal items │ ✅ Yes │ ✅ Yes │
│ Complex 2D layout │ ❌ Painful │ ✅ Made for this │
│ Unknown item count │ ✅ Yes (wrap) │ ⚠️ auto-fill │
│ Overlapping items │ ❌ No │ ✅ Yes │
└─────────────────────┴──────────────────┴──────────────────┘
Rule of thumb:
→ One dimension (row OR column) → Flexbox
→ Two dimensions (rows AND columns) → Grid
→ They work TOGETHER! Use Grid for page layout, Flexbox inside each component
Modern Layout Shortcuts
/* Gap property (works on BOTH flex and grid!) */
/* Replaces the old margin hack for spacing */
.flex-container { display: flex; gap: 1rem; }
.grid-container { display: grid; gap: 1rem; }
/* Aspect ratio */
.card-image {
aspect-ratio: 16 / 9; /* Maintains ratio automatically */
object-fit: cover; /* Fills area without distortion */
}
.avatar {
aspect-ratio: 1 / 1; /* Always square */
border-radius: 50%;
}
/* Logical properties (for RTL/internationalization) */
/* Instead of physical directions (left/right/top/bottom): */
.box {
margin-inline-start: 1rem; /* = margin-left in LTR, margin-right in RTL */
margin-block-end: 0.5rem; /* = margin-bottom */
padding-inline: 1rem; /* Horizontal padding (respects text direction) */
inset-inline-start: 0; /* = left: 0 in LTR */
text-align: start; /* = left in LTR, right in RTL */
}
/* Container Queries (responsive to parent, not viewport!) */
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card { display: grid; grid-template-columns: 150px 1fr; }
}
@container (max-width: 399px) {
.card { display: block; }
}
/* Subgrid (child grid inherits parent's tracks) */
.grid-parent {
display: grid;
grid-template-columns: subgrid; /* Inherits parent's column definitions! */
grid-row: span 3;
}
Which layout challenge frustrates you most? Flexbox, Grid, or something else entirely?
Follow @armorbreak for more practical developer guides.
Top comments (0)