Explain the main axis vs cross axis in Flexbox

Beginner8 min interview
Skills tested:
Defining the main axis from flex-directionKnowing the cross axis is always perpendicular to the main axisMapping justify-content to the main axis and align-items to the cross axisPredicting how flex-direction: column swaps every alignment propertyUnderstanding that reverse directions swap start and end, not orientation

Advertisement

🧩 Scenario

Every Flexbox bug that ends with "I centred it and it went the wrong way" comes from the axes. A card layout that centres perfectly as a row breaks the moment it becomes a column on mobile, because justify-content and align-items silently swapped meaning. Knowing which axis each property targets is the difference between reasoning about a layout and guessing at it.

Architecture Walkthrough

flex-direction Defines the Main Axis

A flex container has two axes, and flex-direction decides which is which. The main axis is the direction items are laid out along. The cross axis is always perpendicular to it.

  • flex-direction: row (the default): main axis is horizontal, cross axis is vertical
  • flex-direction: column: main axis is vertical, cross axis is horizontal
  • flex-direction: row-reverse: main axis is still horizontal, but start and end are swapped
  • flex-direction: column-reverse: main axis is still vertical, with start and end swapped

Note what reverse does and does not do. It does not rotate the axis; it flips the direction of travel along it. In a left-to-right writing mode, row-reverse puts the main start at the right edge, so justify-content: flex-start now pushes items to the right. The axis is still horizontal.

Every Alignment Property Targets One Axis

This is the payoff of understanding the axes. The Flexbox alignment properties are not "horizontal" and "vertical" properties; they are "main axis" and "cross axis" properties.

  • justify-content distributes items along the main axis
  • align-items aligns items on the cross axis
  • align-self overrides align-items for a single item, on the cross axis
  • align-content distributes wrapped lines along the cross axis, and only does anything when there are multiple lines
  • flex-grow, flex-shrink, and flex-basis all operate on the main axis size of items

Because these bind to axes rather than to screen directions, switching flex-direction from row to column swaps the effect of every one of them at once. justify-content: center centres horizontally in a row and vertically in a column. align-items: center does the opposite. This is why a card layout that looks right as a row can break entirely when a media query turns it into a column: the declarations did not change, but what they mean did.

Why the Spec Says Inline and Block

The axes are not truly horizontal and vertical. They follow the document's writing mode and text direction.

In a standard horizontal, left-to-right document, the inline direction is horizontal and the block direction is vertical, so flex-direction: row runs left to right. In a vertical writing mode such as writing-mode: vertical-rl, the inline direction is vertical, so flex-direction: row lays items out top to bottom. In a right-to-left language, row starts at the right edge with no reverse needed.

That is why the spec and the logical property set use inline and block rather than horizontal and vertical, and why flex-start and flex-end are preferable to left and right. Writing justify-content: flex-start produces a layout that works in Arabic and Japanese without change; hard-coding left does not.


Key Code Explained

/* Default: main axis horizontal, cross axis vertical */
.row {
  display: flex;
  flex-direction: row;
  justify-content: center; /* centres HORIZONTALLY (main axis) */
  align-items: center;     /* centres VERTICALLY   (cross axis) */
}

/* Switch direction and BOTH properties swap meaning */
.column {
  display: flex;
  flex-direction: column;
  justify-content: center; /* now centres VERTICALLY   (main axis) */
  align-items: center;     /* now centres HORIZONTALLY (cross axis) */
}

/* reverse flips start/end, it does NOT rotate the axis */
.row-reverse {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-start; /* pushes items to the RIGHT in LTR */
}

/* The responsive trap: the declarations never change, their meaning does */
.card-list {
  display: flex;
  flex-direction: column;
  align-items: center; /* horizontal centring on mobile */
}
@media (min-width: 768px) {
  .card-list {
    flex-direction: row;
    /* align-items: center now means VERTICAL centring.
       If horizontal centring was the goal, justify-content is needed here. */
    justify-content: center;
  }
}

/* align-content only does something when lines WRAP */
.wrapped {
  display: flex;
  flex-wrap: wrap;
  height: 400px;
  align-content: space-between; /* distributes the LINES on the cross axis */
  align-items: center;          /* aligns items WITHIN each line */
}

/* Axes follow writing mode, not the screen */
.vertical-text {
  writing-mode: vertical-rl;
  display: flex;
  flex-direction: row; /* main axis now runs TOP TO BOTTOM */
}

The .card-list media query is the most instructive block. Both breakpoints centre their children, and neither alignment declaration is wrong in isolation, but align-items: center silently changes from horizontal to vertical centring when the direction flips. This is the single most common real-world consequence of not tracking the axes, and it is why reading a Flexbox rule always starts with checking flex-direction.

The .wrapped example shows the third alignment property people miss. align-items positions items inside their line; align-content positions the lines themselves. With a single line, align-content has nothing to distribute and appears to do nothing, which is a frequent source of confusion.


Tradeoffs

PropertyAxisEffect in rowEffect in column
justify-contentMainHorizontal distributionVertical distribution
align-itemsCrossVertical alignmentHorizontal alignment
align-selfCrossVertical, one itemHorizontal, one item
align-contentCrossVertical, lines onlyHorizontal, lines only
flex-grow / shrink / basisMainControls widthControls height

What Interviewers Actually Check

  • Whether you define the axes from flex-direction rather than from screen orientation
  • Whether you can map each alignment property to its axis without hesitation
  • Whether you know switching to column swaps the meaning of every alignment property at once
  • Whether you know reverse flips start and end rather than rotating the axis
  • Whether you mention writing mode, or at least prefer flex-start over left

Follow-Up Questions

  1. What does justify-items do in Flexbox, and why is the answer different from Grid?
  2. When does align-content have a visible effect, and what must be true of the container for it to matter?
  3. How do justify-self and align-self differ in availability between Flexbox and Grid?
  4. In a right-to-left document, does flex-direction: row start on the left or the right, and what does that imply for row-reverse?
  5. How do the gap, row-gap, and column-gap properties map onto the main and cross axes?

Common Candidate Mistakes

  • Memorising justify-content as horizontal and align-items as vertical, which produces wrong predictions the moment flex-direction: column appears
  • Changing flex-direction in a media query without revisiting the alignment properties, so a layout that centred correctly at one breakpoint centres on the wrong axis at another
  • Believing row-reverse makes the main axis vertical, when it only swaps the start and end of a still-horizontal axis
  • Reaching for align-content on a single-line flex container and concluding it does not work, when it only distributes wrapped lines
  • Hard-coding left and right in alignment reasoning and ignoring that writing mode and text direction rotate or flip both axes

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you define both axes for all four flex-direction values?
  • Can you say which alignment property operates on which axis?
  • Can you explain what changes when you switch a container from row to column?
  • Can you explain what reverse changes and what it leaves alone?
  • Can you explain why the spec uses inline and block terminology rather than horizontal and vertical?

Summary

A flex container has a main axis, set by flex-direction, and a cross axis that is always perpendicular to it. With row, the main axis is horizontal; with column, it is vertical. The reverse variants keep the axis orientation and swap only its start and end, so row-reverse with justify-content: flex-start pushes items to the right in a left-to-right document.

Every Flexbox alignment property is defined against an axis rather than a screen direction. justify-content works on the main axis, align-items and align-self on the cross axis, align-content on the cross axis but only for wrapped lines, and flex-grow, flex-shrink, and flex-basis all size items along the main axis. Because of that binding, changing flex-direction swaps what every one of these properties does, which is why responsive layouts that flip direction at a breakpoint must revisit their alignment declarations rather than carry them over.

Finally, the axes follow the writing mode rather than the physical screen. In a vertical writing mode, flex-direction: row runs top to bottom; in a right-to-left document it starts at the right edge. That is why the spec speaks in inline and block terms and why using flex-start and flex-end produces layouts that survive internationalisation while hard-coded left and right reasoning does not.

Frequently Asked Questions

Does the main axis change with flex-direction: row-reverse?

The axis stays horizontal, but its start and end swap. flex-start now means the right edge in a left-to-right writing mode, so justify-content: flex-start pushes items right.

Are the axes always horizontal and vertical?

No. They follow the writing mode. In a vertical writing mode, flex-direction: row runs vertically, which is why the spec uses inline and block terminology rather than horizontal and vertical.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement