LayoutIntermediate10 min06 / 9

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.

One declaration flips the layout model entirely. Before it: block children stack. After it: they line up in a row.
.container {
  display: flex; /* every direct child lines up in a row */
}
Think of it like

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.

justify = main axis. align = cross axis. gap = space between items. These three together handle most real layouts.
.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 */
}
The most-used values for both properties. In practice, center and space-between carry most real-world layouts.
/* 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 */
Three properties. Perfect centering. Something that used to require multiple hacks now fits in one ruleset.
/* 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 */
}
Common mistake

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; column stacks them top-to-bottom and swaps which axis justify and align refer to.
  • `flex-wrap` lets items overflow onto a new line rather than squeezing to fit. Combine it with gap for simple responsive grids.
  • `flex` (on items, not the container) controls how an item grows, shrinks, and what its starting size is.
flex: 1 is shorthand for flex: 1 1 0 — start at zero and grow to fill available space. When siblings all use flex: 1, they share equally.
/* 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 */
Quick check

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?

Note

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.
Practice challenges
Test yourself · earn XP
0/4
Fill in the blank#1

Complete this ruleset so the container's direct children line up horizontally in a single row instead of stacking.

.container {
  display: ;
}
Predict the output#2

What visual result does this ruleset produce for the content inside .centered-page?

predict-output
.centered-page {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
Fix the bug#3

This code has a bug — what's wrong?

fix-bug
.container {
  display: flex;
  align-items: space-between;
  gap: 16px;
}
Fill in the blank#4

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: ; }
Your turn
Practice exercise

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:

solution.css · editable