CSS Flexbox: The Complete Visual Guide with Live Examples
A complete guide to CSS Flexbox — every container and item property explained with live visual demos, practical layout patterns, and copy-ready CSS.
Before Flexbox, centering a div vertically required either a hack (negative margins, absolute positioning with transforms) or a table-cell workaround. Aligning items in a navigation bar meant float: left, clearfix divs, and a prayer. Flexbox — introduced in modern browsers around 2015 and reaching near-universal support — eliminated all of that. It is now the most-used CSS layout module, and understanding it thoroughly makes every other layout problem easier.
This guide covers every Flexbox property with live examples you can see rendering right here in the page, not just code screenshots.
Want to experiment interactively? Open the CSS Flexbox Generator → to build flex containers visually and copy the output CSS.
What is the Flexbox model? Container vs. items
Flexbox works on two levels simultaneously. You apply display: flex to a container, which controls how its direct children — the flex items — are laid out. Properties on the container control overall distribution and alignment. Properties on individual items control how each one sizes and positions itself within that distribution.
The core mental model: Flexbox lays items out along two perpendicular axes.
- Main axis — the primary direction items flow. Horizontal by default (
flex-direction: row). - Cross axis — perpendicular to the main axis. Vertical by default.
How does flex-direction work?
flex-direction sets which direction the main axis runs, and therefore which way items flow.
row(default) — left to rightrow-reverse— right to leftcolumn— top to bottomcolumn-reverse— bottom to top
This property also flips the meaning of justify-content and align-items. When flex-direction: column, justify-content controls vertical spacing and align-items controls horizontal alignment.
/* The four flex-direction values */
.container {
display: flex;
flex-direction: row; /* default */
flex-direction: row-reverse; /* RTL layouts, reversed stacks */
flex-direction: column; /* vertical stacking */
flex-direction: column-reverse;
} How does justify-content control main-axis spacing?
justify-content distributes items along the main axis. The six values cover every meaningful distribution pattern you'll encounter.
.nav {
display: flex;
justify-content: space-between; /* logo left, links right */
}
.centered {
display: flex;
justify-content: center;
}
.spread {
display: flex;
justify-content: space-evenly; /* equal gaps, including edges */
} The difference between space-between, space-around, and space-evenly trips people up. The rule: space-between puts all gaps between items (no outer gap), space-around puts equal space on each side of each item (outer gaps are half size), and space-evenly makes every gap identical including the first and last.
How does align-items control cross-axis alignment?
align-items aligns items on the cross axis. For flex-direction: row, this means vertical alignment within the row.
Note how stretch (the default) makes items fill the full cross-axis height. This is why flex items in a row are often the same height as the tallest item — a very useful default that replaces the old equal-height column tricks.
.container {
display: flex;
align-items: center; /* vertically centered */
align-items: stretch; /* default — fills container height */
align-items: flex-start;
align-items: flex-end;
align-items: baseline; /* aligns text baselines — useful for nav with mixed font sizes */
} How do I center a div with Flexbox?
This is the most-searched Flexbox question. The answer is two lines on the parent:
.parent {
display: flex;
align-items: center; /* vertical center */
justify-content: center; /* horizontal center */
/* parent needs a height: */
height: 100vh; /* or any fixed/percentage height */
}
/* The child needs nothing special */ This works regardless of the child's size. The parent just needs a defined height — 100vh for full-screen centering, or any explicit height for contained layouts.
What is flex-wrap and when do items overflow?
By default, flex items will all squeeze onto one line (flex-wrap: nowrap). When items overflow their container at small screen sizes, the fix is almost always flex-wrap: wrap.
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
/* Items wrap naturally at any screen size */ What is gap, and is it different from grid-gap?
gap sets spacing between flex items without adding margins to the outer edges. It replaced grid-gap (which only worked on Grid) in 2021 when the spec unified it. Use gap — grid-gap is deprecated in the spec (though browsers still support it).
.container {
display: flex;
gap: 16px; /* equal gap between items, no outer gaps */
gap: 16px 24px; /* row-gap column-gap */
row-gap: 16px; /* vertical gap only (relevant with flex-wrap) */
column-gap: 24px; /* horizontal gap only */
}
/* ✅ Use gap instead of margins on items — gap doesn't add space at the edges */
/* ❌ Avoid: .item { margin-right: 16px; } — adds unwanted margin after last item */ How do flex items size themselves? flex-grow, flex-shrink, flex-basis explained
These three properties control how items distribute available space. The shorthand flex combines all three.
What does flex-grow do?
flex-grow defines how much an item expands relative to others when there is extra space. A value of 1 means "take an equal share." A value of 2 means "take twice the share of a 1."
What does flex-basis do?
flex-basis sets the item's starting size before any remaining space is distributed. Think of it as the "ideal size" the browser tries to achieve before growing or shrinking.
.item {
flex-basis: 200px; /* start at 200px, then grow/shrink from there */
flex-basis: auto; /* use the item's content size as the starting point */
flex-basis: 0; /* start from zero — all space is "extra" to distribute */
} What does flex: 1 actually mean?
flex: 1 is the most-used shorthand, but its exact meaning is non-obvious. flex: 1 expands to flex: 1 1 0 — grow factor 1, shrink factor 1, basis of 0. The basis of 0 means every item starts from zero width, and all container space is distributed proportionally by grow factor. This makes all items the same size when they all have flex: 1.
This is different from flex: 1 1 auto, where items start from their content size and only remaining space is distributed.
/* All items equal width: */
.item { flex: 1; } /* = flex: 1 1 0 — start from 0, share equally */
/* Items proportional to content + share remaining space: */
.item { flex: 1 1 auto; } /* start from content size, then share extra */
/* Common sidebar layout: */
.sidebar { flex: 0 0 280px; } /* never grow or shrink — fixed 280px */
.content { flex: 1; } /* take all remaining space */ Practical layout patterns with live demos
How do I build a responsive navigation bar?
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 20px;
}
.nav-links {
display: flex;
gap: 20px;
}
/* The logo, links, and CTA stay on one row,
with space-between pushing logo left and CTA right. */ How do I create a Holy Grail layout with Flexbox?
The Holy Grail layout — header, full-width; then sidebar, content, and optional second sidebar on one row; then footer — is a classic Flexbox pattern.
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main-area {
display: flex;
flex: 1; /* fills remaining space between header and footer */
}
.sidebar {
flex: 0 0 280px; /* fixed width, never grow/shrink */
}
.content {
flex: 1; /* takes all remaining horizontal space */
min-width: 0; /* prevents overflow from long words — see common mistakes */
} How do I make a sticky footer with Flexbox?
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
main {
flex: 1; /* pushes footer to the bottom on short pages */
}
footer {
/* no special sizing needed */
} When should you use Flexbox vs. CSS Grid?
The honest answer: use Flexbox for one-dimensional layouts (a row of items, a column of items), use Grid for two-dimensional layouts (items arranged in rows and columns simultaneously).
Practical heuristics:
- Navigation bar, tag list, button row → Flexbox. Items flow in a line.
- Card grid where columns need to align vertically → Grid. You need rows and columns.
- Centering a single item → either works; Flexbox is two lines, Grid is also two lines.
- Responsive grid that reflows based on available width → Grid with
repeat(auto-fill, minmax(...)). - Complex page layout (header/sidebar/content/footer) → Grid for the outer shell, Flexbox for inner components.
They are not competitors — most pages use both. Grid for the page skeleton, Flexbox for the components inside it.
What are the most common Flexbox mistakes?
Forgetting min-width: 0 on flex items
Flex items default to min-width: auto, which prevents them from shrinking below their content size. This causes overflow when a child contains a long URL, a pre-formatted code block, or a table. The fix:
.flex-item {
min-width: 0; /* allows the item to shrink below content width */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* if you want truncation */
} Using margins instead of gap for spacing
/* ❌ Adds unwanted right-margin after the last item */
.item { margin-right: 16px; }
/* ✅ No outer gaps, consistent spacing */
.container { gap: 16px; } Expecting flex children to inherit flex properties
Flex properties on the container (justify-content, align-items) affect direct children only. Grandchildren are not flex items. If you need to control a nested element, apply display: flex to the direct parent of those elements.
Confusing align-items and align-content
align-items aligns items within a single row (or column). align-content aligns the rows themselves when flex-wrap is active and there are multiple rows. align-content has no effect when all items fit on one line.
What is the browser compatibility for CSS Flexbox?
Flexbox has 99%+ global browser support as of 2026. The unprefixed syntax has been supported since:
- Chrome 29 (2013)
- Firefox 28 (2014)
- Safari 9 (2015)
- Edge 12 (first release, 2015)
No vendor prefixes (-webkit-flex, -ms-flexbox) are needed in any modern codebase. The only edge cases are very old WebView versions in certain mobile apps — if you need to support Android 4.x WebView, prefix. For all web targets in 2026, write unprefixed.
Try it live: Build flex containers visually and copy production-ready CSS with the CSS Flexbox Generator →