skip to content

In a flex container, how do align-items and align-self differ, and what alignment does an item get when neither is declared?

level: juniorimportance: must knowfreq 70%

answer

  1. container default versus per-item override
  2. cross axis, not the main one
  3. align-self: auto looks up the parent
  4. the default is stretch, not start

basics

~20 s

align-items is declared on the flex container and sets the cross-axis alignment for every item; align-self is declared on one item and overrides it for that item only. With neither set, items use the initial value normal, which behaves as stretch.

solid answer

~40 s

Both control the **cross axis** — the axis perpendicular to the one items flow along. `align-items` lives on the flex container and is the default for all of its items; `align-self` lives on an individual item and wins over the container's value for that item alone. `align-self`'s initial value is `auto`, which means "use my parent's `align-items`", so the two form a simple inherit-and-override pair. `align-items` itself starts at `normal`, and in a flex container `normal` behaves as `stretch`: an item whose cross size is `auto` grows to fill the line's cross size. That is why sibling cards end up equal height without you asking. Give the item an explicit cross size, an `auto` cross-axis margin, or a different `align-self` value and the stretch stops.

code

css · 13 lines
css
.toolbar {
  display: flex;
  height: 80px;
  align-items: center;   /* default for every item */
}

.toolbar .logo {
  align-self: flex-start; /* this one item overrides it */
}

.toolbar .divider {
  align-self: stretch;    /* and this one fills the 80px */
}

go deeper

for a junior

Say plainly that align-items is written on the container and align-self on one child, and that the default is stretch. Being able to override one item without touching its siblings is the practical skill being checked.

for a middle

Explain the mechanism: align-self starts at auto, which resolves to the parent's align-items, and align-items starts at normal, which behaves as stretch in flex. Name the conditions that cancel stretch — an explicit cross size or an auto cross margin.

for a senior

Demonstrate diagnosis: when alignment looks dead, check whether spare cross-axis space exists at all before changing values. Be ready to explain baseline alignment and why justify-self is inert on flex items.

for a principal

Own the convention question: decide whether components set their own align-self or accept the container's default, since scattered per-item overrides are what makes a shared layout component impossible to reason about later.

## Two properties, one axis Flex layout has two axes. Items flow along the **main axis**; the **cross axis** runs perpendicular to it. `justify-content` deals with the main axis; `align-items` and `align-self` deal with the cross axis. Everything below is about the cross axis only. ## Container default, item override `align-items` is a container property. It does not do the aligning itself so much as set the default that every child adopts. `align-self` is an item property that overrides that default for one child. The mechanism is explicit in the specification: `align-self`'s initial value is `auto`, and `auto` computes to the value of the parent's `align-items`. So an item always has an effective cross-axis alignment; the only question is whether it came from the container or from an override. ```css .toolbar { display: flex; align-items: center; } /* everyone centres */ .toolbar .logo { align-self: flex-start; } /* except the logo */ ``` ## The default is stretch `align-items` has an initial value of `normal`. In a flex container, `normal` behaves as `stretch`. Stretch means: if the item's cross size is `auto`, grow it so it fills the cross size of the flex line. This single default explains one of flexbox's most-liked behaviours. In a row-direction container, the cross axis is vertical, so every item stretches to the height of the tallest one and you get equal-height siblings without measuring anything. Stretch has conditions, and knowing them is what separates "it just works" from "why isn't it working": - The item's cross size must be `auto`. A declared `height` in a row container (or `width` in a column container) wins, and the item keeps that size. - The item must not have an `auto` margin on the cross axis. An `auto` cross margin absorbs the free space instead, and alignment on that item is ignored altogether. - `stretch` still respects `max-height`/`max-width` and the item's minimum size, so an item will not stretch past its own limits. ## The value list The values you will actually be asked about: - `stretch` — fill the line's cross size (the default, via `normal`). - `flex-start` / `flex-end` — pack to the cross-start or cross-end edge of the line. The axis-relative `start` / `end` and the item-relative `self-start` / `self-end` also work. - `center` — centre within the line. - `baseline` (and `last baseline`) — align the items' text baselines with each other rather than their box edges. Two items with different font sizes or different padding will have their first lines of text sitting on one shared line, which box-edge alignment cannot produce. It is the right choice for a label next to a large heading. ## The property that does not work here Grid has a `justify-self` for positioning a single item along the inline axis of its cell. A flex container has no such thing: `justify-self` is ignored on flex items, because main-axis positioning is a property of the whole line, not of one item. The way to move one flex item along the main axis is an `auto` margin, not `justify-self`. This is a favourite trap in interviews and in real code. ## Cross-axis space has to exist Alignment can only move an item inside space that is there. In a row-direction container whose height is `auto`, the container is exactly as tall as its tallest item, so `align-items: center` has nothing to centre within — the tallest item defines the line and the shorter ones already had room to move. Give the container a height (or let it stretch inside a taller parent) and the effect appears. Candidates who report that `align-items: center` "doesn't work" have usually hit exactly this. ## How to talk about it The clean formulation is: `align-items` is a bulk setting, `align-self` is the exception, and the default is stretch rather than start — which is why flexbox gives you equal heights for free but also why an image in a flex row sometimes distorts when you never asked it to. When you need one item to break ranks, `align-self` is the whole answer; you never need to restructure the markup for it.

  • What does align-items: baseline align that center does not?
    It lines up the items' first text baselines rather than their box edges. Two items with different font sizes or padding will have their first lines of text sitting on one shared line, while `center` would align the boxes and leave the text visibly off. It is the right value for a small label sitting beside a large heading.
  • Why does justify-self have no effect on a flex item?
    Because flexbox has no per-item main-axis alignment: the main axis is distributed for the whole line by `justify-content`. `justify-self` is ignored on flex items entirely. To move one item along the main axis, give it an `auto` margin on that side — the margin absorbs the free space and shifts the item.
  • Why might align-items: center appear to do nothing on a row-direction flex container?
    Usually because the container's height is `auto`, so it is exactly as tall as its tallest item and there is no spare cross-axis space to centre anything within. Setting a height on the container, or letting it stretch inside a taller ancestor, makes the alignment visible immediately.

saying these in an interview costs you the question

  • Thinks align-items goes on the item and align-self on the container
  • Says the default cross-axis alignment is flex-start
  • Uses justify-self to move a single flex item
  • Believes align-self needs !important to beat align-items
  • Confuses align-items with align-content

context