CSS Flexbox
Flexbox is the layout system you'll use most often: it distributes space along a single row or column and aligns items with one or two properties instead of margin arithmetic. By the end of this lesson you'll build navigation bars, centered cards, and equal-height columns without a single float.
1. What is Flexbox?
Before Flexbox, laying items out in a row meant floating them, using inline-block (and fighting whitespace gaps), or abusing tables. Each approach broke down as soon as you wanted vertical centering or equal heights. Flexbox — the Flexible Box Layout Module — solves exactly this class of problem: arranging a set of items along one axis and controlling how leftover space is distributed between them.
You activate it with a single declaration on a parent element. The parent becomes a flex container, and its direct children automatically become flex items:
.container { display: flex; }
That one line changes everything about how the children behave. They line up in a row, shrink to fit their content, and stretch to equal heights. Everything else in this lesson is about fine-tuning that behavior.
2. The two axes
Every flex container has a main axis and a cross axis, and almost every flex property aligns things along one of them. Which direction the main axis runs is set by flex-direction:
| Value | Main axis | Typical use |
|---|---|---|
row (default) | Left → right | Nav bars, button groups, card rows |
row-reverse | Right → left | Mirrored layouts |
column | Top → bottom | Stacked forms, mobile layouts |
column-reverse | Bottom → top | Chat message lists |
Remembering the axes is the key that unlocks Flexbox: justify-content always works along the main axis, and align-items always works along the cross axis. If a property "isn't working," you're almost always aligning on the wrong axis.
3. Distributing space: justify-content
justify-content controls where extra space along the main axis goes. Here is the same three-item row with the three values you'll use most:
.nav { display: flex; justify-content: space-between; /* also try: flex-start | center | space-around | space-evenly */ }
Live result of each value (real flex containers, resize your window to see them adapt):
4. Aligning on the cross axis: align-items
While justify-content distributes items along the row, align-items positions them across it. The default is stretch, which is why flex children magically become equal height. The value you will type most in your career is this one:
.hero { display: flex; justify-content: center; /* horizontal */ align-items: center; /* vertical */ min-height: 60vh; }
Other values: flex-start (top of a row), flex-end (bottom), and baseline (align text baselines — handy for mixed-size labels). A single item can override the group with align-self.
5. Gap, wrapping, and flexible sizing
Three more properties complete your everyday toolkit:
- gap — space between items only, with none leaking outside the container. Use it instead of margins on children; it also works in Grid, so it's one habit for both systems.
- flex-wrap: wrap — lets items flow onto new lines instead of shrinking forever. Combined with a minimum width per item, this is a responsive card layout with zero media queries.
- flex: 1 — set on a child, tells it to grow and share leftover space. Two children with flex: 1 split the row 50/50; give one flex: 2 and it takes twice as much.
.cards { display: flex; flex-wrap: wrap; gap: 16px; } .cards > article { flex: 1 1 220px; /* grow, shrink, ideal width */ }
6. Try it yourself
The editor below is live. Your task: the three boxes are currently squashed to the left. Edit the .box-row rule so the boxes are evenly spread across the full width and vertically centered. Press Run (or Ctrl/Cmd + Enter) to see your result.
7. Quiz — check your understanding
Flexbox Quiz
5 questions · pass at 60%Q1. Which declaration turns an element into a flex container?
display property on the parent element. Its direct children then become flex items automatically.Q2. justify-content aligns items along which axis?
align-items. Which direction the main axis runs depends on flex-direction.Q3. You want space between flex items, but none at the edges of the container. The cleanest way is:
gap adds space only between items — no leaking margins to cancel at the edges, and the same property works in CSS Grid.Q4. Which property must be set on a flex item (not the container)?
flex (grow / shrink / basis) describes how one child sizes itself. The other three configure the container as a whole.Q5. To perfectly center one child both horizontally and vertically, the container needs:
justify-content, center on the cross axis with align-items.