CSS Flexbox: axes, alignment, and flexible sizing · Lesson 3 of 5

Lesson 03: Turning the main axis with flex-direction

Lesson objectives:

  • Say what flex-direction does and name its four values.
  • Explain why justify-content is not "the horizontal property."
  • Predict which property moves items vertically once the main axis is a column.

Prerequisites: Lesson 02 (justify-content = main axis, align-items = cross axis) | Previous << 02 | Next 04 >>

The moment "justify-content = horizontal" betrays you

In Lesson 02 you learned justify-content moves items left and right. That is true — until it isn't. The instant you stack items in a column, justify-content starts moving them up and down, and if you memorized it as "the horizontal one," you are now fighting your own layout. The people who never get comfortable with Flexbox are usually the ones who learned the properties by their default direction instead of by their axis. This lesson swaps "horizontal" for the thing that is actually true and never changes.

Explanation

flex-direction sets how flex items are placed in the container — it defines the main axis and the direction items flow1. It has four values, and the default is row1:

  • row (default): main axis runs along the row, left to right — the horizontal you already know.
  • row-reverse: same axis, but items start from the right.
  • column: the main axis now runs top to bottom, in the block direction2.
  • column-reverse: same vertical axis, items start from the bottom.

Here is the rule that does not change: justify-content always follows the main axis, and align-items always follows the cross axis. flex-direction decides where the main axis points, so it decides what each of those two properties actually does. Nothing about the properties changes — the axis they are pinned to just rotates.

Read the diagram top-down: flex-direction is the switch. Pick row and the main axis is horizontal, so justify-content is horizontal. Pick column and the main axis is vertical, so the same justify-content is now vertical. The property stayed the same; only the axis it rides rotated ninety degrees.

This is also why vertical menus and sidebars are natural in Flexbox: set flex-direction: column and your items stack, then justify-content spaces them vertically and align-items handles their left-right alignment. Same two properties, rotated axis.

Start and end, not left and right

Here is why this course keeps saying "main-start" instead of "left." Flexbox makes no assumption about the writing mode of the document2. With flex-direction: row in English, the start edge of the main axis is on the left and the end edge on the right — but in Arabic, a right-to-left language, the start edge is on the right and the end on the left2. The CSS did not change; the start end of the axis moved.

That is what flex-start and flex-end actually name: the start and end lines of an axis, resolved against the document's writing direction2. In both the English and Arabic cases above the cross axis still starts at the top and ends at the bottom, because both are horizontal writing modes2. The bare values start and end are writing-mode aware in exactly the same way3.

Practically: if you write justify-content: flex-end and the item lands on the wrong side, check the writing direction before you doubt the property. The row and row-reverse values are affected by the flex container's directionality — under a right-to-left direction, row runs right to left and row-reverse runs left to right1.

What the -reverse values actually reverse

row-reverse and column-reverse keep the axis where it is and swap which end is main-start1. Items then lay out from the opposite end and in the opposite visual order. This is genuinely useful — and it carries a cost worth knowing before you reach for it.

Using row-reverse or column-reverse creates a disconnect between the visual order on screen and the DOM order in your markup. Screen reader users follow the DOM order, so they receive the content in a different sequence than sighted users see it, which adversely affects people navigating with assistive technology1. If the visual order carries meaning, reorder your HTML instead of reversing it in CSS.

There is also a shorthand worth recognizing when you read other people's code: flex-flow combines flex-direction and flex-wrap into one declaration, so flex-flow: row wrap sets both at once2. Lesson 05 covers the wrapping half.

Worked example (follow along)

A vertical sidebar nav, evenly spaced top to bottom, each link centered left-to-right:

Trace it with the rule. flex-direction: column makes the main axis vertical. justify-content: space-between acts on the main axis, so it spreads the links vertically — first at the top, last at the bottom, gaps even. align-items: center acts on the cross axis, which is now horizontal, so each link is centered left-to-right. If you had expected justify-content to space them horizontally, the column flip is exactly what would have surprised you.

Your turn (faded example)

You want three buttons stacked vertically and pinned to the bottom of a tall container. Fill in the two lines:

Answer: flex-direction: column (main axis becomes vertical) and justify-content: flex-end (main-end is now the bottom). Because the main axis points down, flex-end means bottom, and justify-content is the property that moves along that axis. Read it as "which axis, which end," and the column flip stops being a trap.

Summary + what's next

flex-direction sets where the main axis points; justify-content follows the main axis and align-items follows the cross axis, no matter which way they point. Trade "horizontal/vertical" for "main/cross" and the column flip stops surprising you. So far every item has taken its natural size. Next we let items share the leftover space — where flex-grow, flex-shrink, and flex-basis come in, and where the biggest myth of all lives: what flex: 1 actually divides up.

Footnotes

  1. MDN: flex-direction — https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/flex-direction 2 3 4 5

  2. MDN: Basic concepts of flexbox — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Basic_concepts 2 3 4 5 6

  3. MDN: Aligning items in a flex container — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Aligning_items

Exercises

01

In your own file, build a display: flex container with three children and a fixed height. Add justify-content: center and watch it center horizontally. Now add flex-direction: column and reload. Note which way the items and the centering moved.

Level 1 (warm-up)
Done criteria · checked locally
02

Predict, before reloading, what align-items: flex-end does in a flex-direction: column container. Then verify.

Level 2 (advanced)
Done criteria · checked locally

My note

Jot down thoughts, sticking points, things you didn't get. Written to this course's appendix only — the lesson file is never touched.