Flexbox
Flexbox is CSS's one-dimensional layout superpower — once you understand its two axes and a handful of properties, you'll be arranging, spacing, and centering elements effortlessly.
For a long time, getting things to line up in CSS felt like an ongoing battle. Centering something vertically? Floating columns that didn't collapse? Equal-height cards? Developers reached for hacks — negative margins, display: table, position: absolute gymnastics — just to get basic layouts working.
Then Flexbox arrived and almost overnight those problems dissolved. Flexbox (short for Flexible Box Layout) is a CSS layout mode designed for arranging items along a single line — either a row or a column. It gives you precise, readable control over how items are spaced, sized, and aligned, with property names that say what they mean.
All you need to activate it is one line on a parent element. From that moment, every direct child becomes a flex item the browser arranges for you.
.container {
display: flex; /* every direct child lines up in a row */
}Think of a toolbox tray
Imagine a long, shallow tray in a toolbox. The tray is the flex container. The tools sitting in it are the flex items. The tray decides how they're arranged — packed tight, spread evenly, centered. Each tool doesn't choose its own position; the tray does.
When you write display: flex, you turn an element into that tray.
#The Two Axes — the Key to Everything
Every Flexbox layout has two axes:
- Main axis — the direction items are laid out. Horizontal (left-to-right) by default.
- Cross axis — perpendicular to that. Vertical by default.
This is the unlock for all of Flexbox: anything with justify in its name controls spacing on the main axis. Anything with align controls position on the cross axis. Once you see that pattern, the property names stop feeling like guesswork.
.container {
display: flex;
justify-content: space-between; /* main axis: spread items with gaps */
align-items: center; /* cross axis: vertically centered */
gap: 16px; /* uniform space between every item */
}/* justify-content: controls main-axis spacing */
justify-content: flex-start; /* pack at the start (default) */
justify-content: center; /* center the whole group */
justify-content: space-between; /* max space between items; none at edges */
justify-content: space-evenly; /* equal space including outer edges */
/* align-items: controls cross-axis alignment */
align-items: stretch; /* fill container height (default) */
align-items: center; /* vertically centered */
align-items: flex-start; /* hug the top edge */
align-items: flex-end; /* hug the bottom edge *//* Combining both: the classic recipe for perfect centering */
.centered-page {
display: flex;
justify-content: center; /* horizontal center */
align-items: center; /* vertical center */
height: 100vh; /* give it height to center within */
}gap only adds space between items — not at the edges
gap creates space between flex items, but never before the first item or after the last. For padding inside the container edges, use padding on the container itself. Mixing per-child margin with gap leads to uneven spacing that is difficult to track down.
#flex-direction, flex-wrap, and flex on Items
Three more tools round out the essential Flexbox toolkit:
- `flex-direction` changes the main axis direction.
row(default) lays items left-to-right;columnstacks them top-to-bottom and swaps which axisjustifyandalignrefer to. - `flex-wrap` lets items overflow onto a new line rather than squeezing to fit. Combine it with
gapfor simple responsive grids. - `flex` (on items, not the container) controls how an item grows, shrinks, and what its starting size is.
/* flex-direction: column stacks items vertically */
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 8px;
}
/* flex-wrap: wrap lets items flow to a new row */
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
/* flex on items: grow/shrink/basis shorthand */
.sidebar { flex: 0 0 240px; } /* fixed, won't grow or shrink */
.main-content { flex: 1; } /* fill all remaining space */You have a flex container with three items. You want maximum space between them, but no extra space at the left or right edge of the container. Which value should you use?
Flexbox is one-dimensional — CSS Grid handles two
Flexbox arranges items along a single axis at a time (a row or a column). When you need to control both rows and columns simultaneously — a page-level grid, a photo mosaic — that is the job of CSS Grid. The two tools complement each other perfectly, and most modern layouts use both.
Key takeaways
- Write display: flex on a container and its direct children immediately line up as flex items in a row.
- justify-content controls spacing on the main axis; align-items controls alignment on the cross axis — both always say what they do.
- Combine justify-content: center and align-items: center to perfectly center anything, horizontally and vertically, with just three CSS lines.
- Use gap for clean spacing between items, flex-direction: column to stack vertically, and flex-wrap: wrap for responsive multi-line layouts.
- Apply flex: 1 to a child to make it grow into all available space — the foundation of fluid multi-column layouts.
Complete this ruleset so the container's direct children line up horizontally in a single row instead of stacking.
.container { display: ; }
What visual result does this ruleset produce for the content inside .centered-page?
.centered-page {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}This code has a bug — what's wrong?
.container {
display: flex;
align-items: space-between;
gap: 16px;
}Complete the two children so the sidebar stays a fixed 240px while the main content grows to fill all remaining space.
.sidebar { flex: 0 0 240px; } .main-content { flex: ; }
Build a navigation bar using Flexbox. The nav should have a logo on the left and three links on the right, all vertically centered within a 64px tall bar. Add 24px of gap between the links and 32px of horizontal padding on the container.
Try it live — edit the code and hit Run to see it rendered: