TL;DR
- Flexbox is a one-dimensional layout system — it works along a single axis (row or column)
- Master the three core properties: justify-content (main axis), align-items (cross axis), and gap
- Use flex: 1 to make items grow equally, flex: none to keep items at their intrinsic size
- Flexbox is ideal for navbars, card rows, form layouts, and centering — use Grid for full page layouts
The Flex Container
Everything starts with display: flex on the parent. This creates a flex container and turns direct children into flex items.
.container {
display: flex;
flex-direction: row; /* default — items flow left to right */
justify-content: flex-start; /* default — pack items to the start */
align-items: stretch; /* default — items stretch to fill container height */
gap: 1rem; /* spacing between items */
}
flex-direction
Controls the main axis. row (default) is horizontal, column is vertical. The cross axis is always perpendicular.
/* Vertical stack */
.stack {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
/* Reverse order without changing HTML */
.reversed {
display: flex;
flex-direction: row-reverse;
}
flex-wrap
By default, flex items try to fit on one line. flex-wrap: wrap lets them flow to the next line:
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag {
padding: 0.25rem 0.75rem;
background: hsl(217, 91%, 95%);
border-radius: 9999px;
}
Alignment Deep Dive
This is where Flexbox shines. The two key axes:
- Main axis (direction of flex-direction): controlled by justify-content
- Cross axis (perpendicular): controlled by align-items
/* Center everything — the classic */
.center-all {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Space items evenly */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
/* Push last item to the end */
.card-footer {
display: flex;
align-items: center;
gap: 0.5rem;
}
.card-footer .price {
margin-left: auto; /* pushes to the right */
}
The flex Shorthand
The flex property on items controls how they grow and shrink. It's shorthand for flex-grow, flex-shrink, and flex-basis.
/* Common patterns */
.item { flex: 1; } /* grow equally, basis 0 — equal width items */
.item { flex: none; } /* don't grow or shrink — intrinsic size */
.item { flex: 0 1 auto; } /* default — don't grow, can shrink, auto basis */
.item { flex: 1 1 0; } /* same as flex: 1 — grow and shrink equally */
/* Sidebar + main content */
.sidebar { flex: 0 0 280px; } /* fixed 280px, won't grow or shrink */
.main { flex: 1; } /* takes remaining space */
Common Patterns
Navbar
<nav class="nav">
<a href="/" class="nav-logo">Logo</a>
<div class="nav-links">
<a href="/about">About</a>
<a href="/work">Work</a>
<a href="/contact">Contact</a>
</div>
</nav>
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 2rem;
}
Card Layout with Footer Pinned to Bottom
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-body {
flex: 1; /* grows to push footer down */
}
.card-footer {
margin-top: auto; /* alternative: pin to bottom */
}
Holy Grail Centering
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
That's it. Three lines. This is why Flexbox exists.
Best Practices
- Do use gap for spacing — it replaced the old margin hack on flex items
- Do use flex: 1 for equal-width items instead of calculating percentages
- Do use margin-left: auto (or margin-top: auto in columns) to push items to the end
- Don't use Flexbox for two-dimensional grid layouts — use CSS Grid
- Don't set width on flex items when you should use flex-basis
- Don't forget min-width: 0 on flex items with text — prevents overflow from long strings
Common Mistakes
- Text overflow — flex items have min-width: auto by default. Long words or URLs won't shrink below their content size. Fix with min-width: 0 and overflow: hidden
- Centering with
margin: auto— this works, but justify-content and align-items are clearer and more maintainable - Mixing flex and width — width: 33.33% on a flex item ignores the gap. Use flex: 1 instead
- Forgetting
flex-wrap— items will overflow the container on small screens if you don't wrap
Tools to Explore
- Flexbox Playground — visually experiment with every flex property
- Spacing Calculator — generate consistent spacing scales for your flex layouts