CSSNov 4, 2026 · 6 min read

easily understand flexbox

For the first three years I wrote CSS, flexbox and I had an arrangement. I would type display: flex, then guess at justify-content and align-items until the boxes landed somewhere reasonable. It worked about 70 percent of the time. The other 30 percent I sat in devtools toggling properties like a slot machine, hoping for three boxes in a row. (You know the feeling. Everyone knows the feeling.)

Turns out the whole thing is two axes and a handful of properties. This is the post I wish existed back then, with pictures, because flexbox is one of those things that clicks visually or not at all.

The only mental model you need

flexbox lays things out along two axes: the main axis and the cross axis. Every property you are about to learn answers one of two questions. Where do things go along the main axis? Where do they go along the cross axis? That is genuinely all of it.

Diagram of a flex container showing the horizontal main axis and the vertical cross axis

The display switch

One line turns any container into a flex container, and its children line up in a row, left to right:

flex-basics.cssTypeScript
.container {
  display: flex;
}

That is the on switch. Everything below only works once this line exists, which is worth saying because I once spent twenty minutes wondering why justify-content was doing nothing. It was doing nothing because I forgot the switch.

flex-direction flips the axes

By default the main axis runs left to right (row). Set flex-direction to column and the main axis runs top to bottom instead. The axes flip, which means justify-content and align-items swap jobs. Forgetting this is why centering "randomly breaks" when you switch a layout from row to column.

flex-direction.cssTypeScript
.container {
  display: flex;
  flex-direction: column; /* main axis is now vertical */
}

justify-content runs the main axis

This is the one everyone mixes up, so here are all six values doing the same job on the same three boxes:

Diagram showing the six justify-content values: flex-start, flex-end, center, space-between, space-around, space-evenly

In practice you will use three of these for 95 percent of layouts: flex-start, center, and space-between. Learn those cold, look up the rest when you need them.

align-items runs the cross axis

Same idea, other direction. The default is stretch, which is why your boxes fill the container height and you never questioned it:

Diagram showing the four align-items values: stretch, flex-start, flex-end, center

The centering trick, finally explained

The most googled CSS snippet of all time, and now you can read it instead of copying it:

center.cssTypeScript
.center {
  display: flex;
  justify-content: center; /* center along the main axis */
  align-items: center;     /* center along the cross axis */
}

Center on one axis, center on the other. Done. No absolute positioning, no transform hacks, no margin auto prayer.

gap killed the margin hacks

Remember putting margin-right on every child except the last one? gap does it properly, with even spacing that does not collapse or double up:

gap.cssTypeScript
.container {
  display: flex;
  gap: 12px; /* space between children, nothing else */
}

Try it live

Same three boxes. Flip the direction, move them along each axis, watch what changes. This is faster than reading my explanation a second time:

Live: flexbox playground
flex-direction
justify-content
align-items
1
2
3

So, what have I learnt?

  • flexbox is two axes. Name the axis before you reach for a property and half the confusion disappears.
  • justify-content is the main axis, align-items is the cross axis. Mixing those two up was 90 percent of my problem.
  • flex-direction: column flips the axes, which is why centering breaks when you change direction.
  • Centering is two lines and now I know which two and why.
  • gap over margins, every single time.