In a CSS flex container, what are the main axis and the cross axis, and what changes when flex-direction is set to column?
answer
- one direction at a time
- the second axis is derived, not fixed
- start and end edges, not left and top
- justify versus align naming
- column swaps which property does what
basics
~20 sflex-direction picks the main axis, the direction items are placed in, and the cross axis is always perpendicular to it. With flex-direction: column the main axis becomes vertical, so justify-content now positions items vertically and align-items horizontally.
solid answer
~40 sFlexbox lays items out along one axis at a time. `flex-direction` chooses that **main axis** — horizontal for `row`, vertical for `column` — and the **cross axis** is whatever runs perpendicular to it. Each axis has a start and an end edge, which is what `flex-start` and `flex-end` refer to; they are not synonyms for left and top. The property split follows the naming: `justify-content` distributes items along the main axis, `align-items` and `align-self` position them on the cross axis, and the `flex-grow`/`flex-shrink`/`flex-basis` trio always sizes the **main** dimension. So switching to `column` swaps everything: `justify-content` becomes vertical, `align-items` becomes horizontal, `flex: 1` now distributes height instead of width, and an item's `width` is now its cross size, which the flex algorithm leaves alone.
code
css · 14 lines.row {
display: flex;
flex-direction: row;
justify-content: center; /* horizontal: main axis */
align-items: center; /* vertical: cross axis */
}
.column {
display: flex;
flex-direction: column;
min-height: 300px; /* free space to distribute */
justify-content: center; /* vertical: main axis */
align-items: center; /* horizontal: cross axis */
}go deeper
Be able to say that flex-direction sets the main axis, that the cross axis is perpendicular to it, and that column makes the main axis vertical.
Explain the mapping property by property: justify on the main axis, align on the cross axis, and the flex sizing trio always negotiating the main dimension. Expect to be asked what column changes.
Demonstrate the diagnosis: when a responsive layout flips to column and the centring breaks, name the axis swap as the cause rather than adding both properties and hoping. Note that a content-height column has no free space to distribute.
Own the convention that keeps this from recurring: axis-relative keywords over physical sides, and direction changes made at a single container rather than scattered, so a breakpoint switch does not silently reinterpret every alignment rule beneath it.
## One axis at a time Flexbox is a one-dimensional layout system: it arranges items along a single line at a time. `flex-direction` decides which direction that line runs, and everything else in the model is defined relative to it. - `row` (the initial value): the main axis is horizontal; items are placed left to right in a standard left-to-right horizontal writing mode. - `row-reverse`: still horizontal, but placement starts from the opposite end. - `column`: the main axis is vertical; items are placed top to bottom. - `column-reverse`: vertical, starting from the bottom. The **cross axis** is always perpendicular to the main axis. It is not "the vertical one" — it is vertical only for as long as the main axis is horizontal. ## The four edges Each axis has two edges: main-start and main-end, cross-start and cross-end. Items are packed from main-start toward main-end; when wrapping is enabled, the resulting lines stack from cross-start toward cross-end. Every keyword ending in `-start` or `-end` names one of these edges rather than a physical side, which is precisely why `justify-content: flex-start` pushes items to the **top** of a `column` container. ## Which property follows which axis | Property | Axis | Declared on | | --- | --- | --- | | `justify-content` | main | container | | `align-items`, `align-self` | cross | container, item | | `align-content` | cross (stacking of wrapped lines) | container | | `flex-grow`, `flex-shrink`, `flex-basis` | main | item | The naming is a dependable mnemonic: `justify-*` acts on the main axis, `align-*` acts on the cross axis, and the `flex-*` sizing properties always size the main dimension. ## What flex-direction: column actually changes In a horizontal writing mode, switching a container from `row` to `column`: - makes `justify-content` move items up and down instead of left and right; - makes `align-items` move items left and right instead of up and down; - makes `flex-basis` and shorthands like `flex: 1` distribute **height**, because an item's main size is now its height; - means the default cross-axis stretch now stretches items to the container's **width** rather than its height; - makes `flex-wrap: wrap` create new columns rather than new rows. Nothing else changes. The container is still a block-level box, the children are still flex items, and no additional dimension of layout has appeared — a column flex container is still one-dimensional. ## The classic bug Someone centres a toolbar with `justify-content: center`, later switches the container to `column` at a small breakpoint, and the horizontal centring vanishes. The declaration did not stop working: it still centres on the main axis, and the main axis is now vertical. The property that now controls horizontal position is `align-items`. ```css .stack { display: flex; flex-direction: column; align-items: center; /* horizontal — cross axis */ justify-content: center; /* vertical — main axis */ } ``` A second, closely related surprise: main-axis distribution in a `column` container often looks like it does nothing. That is because a block-level container's height is content-based, so there is no free space on the vertical main axis to distribute. Give the container a `height`, a `min-height`, or make it a flex item that grows, and the same declaration starts behaving. ## Main size and cross size The specification talks about an item's *main size* and *cross size* rather than width and height, because which physical dimension those map to depends on `flex-direction`. In a row container, `width` is the main size — the flex algorithm may grow or shrink it — and `height` is the cross size. In a column container the roles swap: `width` becomes the cross size and is left to ordinary sizing and stretching, while `height` is what `flex-grow` and `flex-shrink` negotiate. This is why a fixed `width` on an item behaves so differently in the two directions. ## The reverse values `row-reverse` and `column-reverse` swap main-start with main-end. Items are laid out from the far end, and main-axis alignment follows them, so `flex-start` in a `row-reverse` container is the right-hand edge. What they do **not** change is the document: DOM order, painting order and keyboard focus order all stay in source order, so a reversed visual sequence no longer matches the order a keyboard or screen-reader user encounters. They also flip which edge overflowing content spills toward, which is a common source of confused scroll behaviour. ## Axes are relative, not physical One last framing that pays off later: `row` and `column` are defined against the container's inline and block axes, not against the screen. Change the writing direction and the physical meaning of `row` changes with it — which is exactly what makes flex-relative keywords worth using instead of hardcoded sides.
- What exactly does flex-direction: row-reverse change, and what does it leave alone?It swaps main-start and main-end, so items are laid out from the right in a left-to-right context and main-axis alignment flips with them. It leaves the document alone: DOM order, painting order and keyboard focus order stay in source order, so the visual sequence and the tab sequence diverge. It also flips which edge overflow spills toward.
- In a column container, why does main-axis distribution often appear to do nothing?Because there is no free space. A block-level container's height is determined by its content, so the items already fill the main axis exactly and there is nothing left to distribute. Give the container a height or min-height, or let it grow as a flex item itself, and the distribution becomes visible.
- How do you work out which axis a property acts on without memorising a table?Read the prefix. Anything named `justify-*` acts on the main axis, anything named `align-*` acts on the cross axis, and the `flex-*` sizing properties always size the main dimension. Then ask which physical direction the main axis currently points, which is entirely decided by `flex-direction`.
saying these in an interview costs you the question
- Says justify-content always centres things horizontally
- Thinks the cross axis is always the vertical one
- Believes flex-direction: column gives two-dimensional layout
- Assumes flex-basis always resolves against width
- Reads flex-start as a synonym for the left edge