Explain the main axis vs cross axis in Flexbox
Advertisement
🧩 Scenario
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 verticalflex-direction: column: main axis is vertical, cross axis is horizontalflex-direction: row-reverse: main axis is still horizontal, but start and end are swappedflex-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-contentdistributes items along the main axisalign-itemsaligns items on the cross axisalign-selfoverridesalign-itemsfor a single item, on the cross axisalign-contentdistributes wrapped lines along the cross axis, and only does anything when there are multiple linesflex-grow,flex-shrink, andflex-basisall 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
| Property | Axis | Effect in row | Effect in column |
|---|---|---|---|
justify-content | Main | Horizontal distribution | Vertical distribution |
align-items | Cross | Vertical alignment | Horizontal alignment |
align-self | Cross | Vertical, one item | Horizontal, one item |
align-content | Cross | Vertical, lines only | Horizontal, lines only |
flex-grow / shrink / basis | Main | Controls width | Controls height |
What Interviewers Actually Check
- Whether you define the axes from
flex-directionrather than from screen orientation - Whether you can map each alignment property to its axis without hesitation
- Whether you know switching to
columnswaps the meaning of every alignment property at once - Whether you know
reverseflips start and end rather than rotating the axis - Whether you mention writing mode, or at least prefer
flex-startoverleft
Follow-Up Questions
- What does
justify-itemsdo in Flexbox, and why is the answer different from Grid? - When does
align-contenthave a visible effect, and what must be true of the container for it to matter? - How do
justify-selfandalign-selfdiffer in availability between Flexbox and Grid? - In a right-to-left document, does
flex-direction: rowstart on the left or the right, and what does that imply forrow-reverse? - How do the
gap,row-gap, andcolumn-gapproperties map onto the main and cross axes?
Common Candidate Mistakes
- Memorising
justify-contentas horizontal andalign-itemsas vertical, which produces wrong predictions the momentflex-direction: columnappears - Changing
flex-directionin 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-reversemakes the main axis vertical, when it only swaps the start and end of a still-horizontal axis - Reaching for
align-contenton a single-line flex container and concluding it does not work, when it only distributes wrapped lines - Hard-coding
leftandrightin 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-directionvalues? - Can you say which alignment property operates on which axis?
- Can you explain what changes when you switch a container from
rowtocolumn? - Can you explain what
reversechanges 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.
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