skip to content

Flexbox Layout

One-dimensional layout: a container distributes free space along a main axis and aligns items on the cross axis. It is the most-asked layout topic because almost every component uses it and its sizing algorithm is genuinely subtle.

part ofCSSoverview, primer and where to startread it →
on this pageshow

explore

questions

28

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

open as a page

In Flexbox, how can you tell whether a CSS property belongs on the flex container or on a flex item, and what happens if you declare it on the wrong one?

level: juniorimportance: must knowfreq 58%

basics

~20 s

Container properties set up the layout itself: display, flex-direction, flex-wrap, flex-flow, justify-content, align-items, align-content and gap. Item properties describe one box's own participation: order, flex-grow, flex-shrink, flex-basis, the flex shorthand and align-self. Declared on the wrong box, they are silently ignored.

open as a page

In CSS, what is the difference between display: flex and display: inline-flex on an element?

level: juniorimportance: must knowfreq 62%

basics

~20 s

Both lay the children out identically as flex items. The difference is the container's own box: display: flex is block-level, so it takes its own line and fills the available width, while display: inline-flex is inline-level and sits inside surrounding text.

open as a page

Using CSS Flexbox, how do you center a single child both horizontally and vertically inside its parent, and what does the parent need for the vertical centering to be visible?

level: juniorimportance: must knowfreq 86%

basics

~20 s

Set display: flex, justify-content: center and align-items: center on the parent, and give that parent a height, such as min-height: 100vh. Without a height the parent shrink-wraps its child, so there is no vertical free space to center in.

open as a page

In CSS Flexbox, what do the shorthand values flex: 1, flex: auto, flex: none, and flex: initial each expand to?

level: juniorimportance: must knowfreq 85%

basics

~20 s

flex: 1 expands to flex: 1 1 0%, flex: auto to 1 1 auto, flex: none to 0 0 auto, and flex: initial to 0 1 auto. The three parts, in order, are flex-grow, flex-shrink, and flex-basis.

open as a page

In CSS Flexbox, what is the initial value of flex-wrap, and what happens to the items when the flex container is too narrow to fit them all?

level: juniorimportance: must knowfreq 72%

basics

~20 s

flex-wrap defaults to nowrap, so every item stays on a single flex line: items shrink toward their minimum size and then overflow the container. Setting flex-wrap: wrap lets the container break items onto multiple flex lines instead.

open as a page

In a flex container, how do justify-content: space-between, space-around, and space-evenly differ in where they put the leftover main-axis space?

level: middleimportance: must knowfreq 72%

basics

~20 s

space-between puts all leftover main-axis space between the items and none at the edges; space-around gives each item an equal share on both of its sides, so edge gaps are half the inner gaps; space-evenly makes every gap, edges included, identical.

open as a page

In a CSS flex container, what are the main axis and the cross axis, and what changes when flex-direction is set to column?

level: middleimportance: must knowfreq 80%

basics

~20 s

flex-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.

open as a page

Why does a flex item often refuse to shrink below the width of its content, and what does setting min-width: 0 on it change?

level: middleimportance: must knowfreq 66%

basics

~20 s

Flex items default to min-width: auto, which floors their main size at roughly their min-content size, so long content overflows the container instead of shrinking. Setting min-width: 0, or any overflow value other than visible, removes that floor.

open as a page

A flex item in a row-direction container declares both width: 200px and flex-basis: 100px. Which value determines its size, and when does flex-basis: auto defer to width?

level: middleimportance: must knowfreq 60%

basics

~20 s

flex-basis wins: a definite flex-basis overrides width on the main axis, so the item starts at 100px. flex-basis: auto is the exception, since auto tells the item to look up its width, and only if that is auto too does it use its content size.

open as a page

Three items in a flex row all have flex-grow: 1 but different amounts of text, and they end up unequal widths. How does flex-grow actually distribute space, and what would make them equal?

level: middleimportance: must knowfreq 68%

basics

~20 s

flex-grow shares only the leftover free space, not the whole container. With flex-basis: auto each item starts at its content width and then adds an equal slice of the remainder, so they stay unequal. Use flex: 1, which sets flex-basis to 0, for equal widths.

open as a page

What does the CSS order property change about a flex item's presentation, and what does it leave unchanged?

level: middleimportance: must knowfreq 56%

basics

~20 s

order changes only the visual and paint sequence of flex or grid items inside their container. The DOM is untouched, so keyboard tab order, screen-reader reading order, and JavaScript traversal all still follow source order.

open as a page

An <img> placed directly inside a display: flex row container renders taller and visibly distorted instead of at its natural size. What causes that, and how do you fix it?

level: juniorimportance: should knowfreq 47%

basics

~20 s

A flex container stretches items along the cross axis by default, so an image with no set height is stretched to the height of the tallest item on the line while its width stays intrinsic, distorting it. Stop the stretch with align-self: flex-start or an explicit size.

open as a page

You set align-content: center on a flex container and nothing moved. Why does align-content so often have no effect, and how is it different from align-items?

level: middleimportance: should knowfreq 48%

basics

~20 s

align-content aligns whole flex lines, so it does nothing unless flex-wrap has actually produced more than one line; align-items is what positions items inside their own line. Either way, there must be spare cross-axis space for the effect to be visible.

open as a page

In a flex container, what does the gap property give you that per-item margins do not, and how does gap change the space justify-content has to distribute?

level: middleimportance: should knowfreq 52%

basics

~20 s

gap sets a fixed space between adjacent flex items only, never at the container's outer edges, and it is reserved before free space is computed, so justify-content distributes only what remains after the gaps are paid for.

open as a page

In CSS Flexbox, what happens to a child's display, float and vertical-align once its parent becomes a flex container?

level: middleimportance: should knowfreq 45%

basics

~10 s

Flex items are blockified: display: inline and inline-block compute to block, float and clear stop having any effect, and vertical-align is ignored. Item margins also never collapse, with each other or with the container.

open as a page

A row of flex cards renders at equal heights, but each card's action button sits directly under its text, so the buttons don't line up across cards. In CSS, how do you pin every button to the bottom of its own card?

level: middleimportance: should knowfreq 44%

basics

~20 s

Make each card its own column flex container and give the button margin-top: auto. The row's default stretch already makes the cards equal height; the auto margin then pushes the button to the bottom of that stretched height, so buttons align across the row.

open as a page

In a Flexbox nav bar whose children are a logo and several links, how do you push just the last link to the far right while the others stay grouped on the left?

level: middleimportance: should knowfreq 48%

basics

~20 s

Give the last link margin-left: auto. In a flex container an auto margin absorbs all remaining free space in the direction it points, so that item is shoved to the right edge while its siblings stay packed on the left.

open as a page

What does it take to make a single line of text truncate with text-overflow: ellipsis when that text lives inside a flex item?

level: middleimportance: should knowfreq 52%

basics

~20 s

Three declarations on the block element holding the text — overflow: hidden, white-space: nowrap, text-overflow: ellipsis — plus min-width: 0 on every row-direction flex item above it, so the box is allowed to be narrower than the text.

open as a page

In a CSS flex container with flex-wrap: wrap, how does the browser decide which items end up on each flex line, and does the gap property affect that decision?

level: middleimportance: should knowfreq 44%

basics

~20 s

Items are collected greedily in order: each item's hypothetical main size (its flex-basis clamped by min and max) plus the gap is added to the current line, and a new line starts as soon as the next item would not fit.

open as a page

A flex container has justify-content: space-between, but one of its items also has margin-left: auto and the spacing comes out wrong. How do auto margins interact with alignment on a flex item?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Auto margins absorb all remaining positive free space on a flex line before justify-content runs, so justify-content has nothing left to distribute and looks ignored. An auto margin on the cross axis likewise takes precedence over align-self.

open as a page

In CSS Flexbox, why does flex-direction: row lay items out right-to-left when the container's direction is rtl, and what does that mean for how you write layout rules?

level: seniorimportance: should knowfreq 33%

basics

~20 s

Flexbox axes are writing-mode relative, not physical: row follows the container's inline axis, whose start edge is the right side under direction: rtl, and column follows the block axis. Flex-relative keywords flip automatically; hardcoded left and right in your CSS do not.

open as a page

How would you build a holy-grail page layout — header, footer, fixed-width left and right sidebars and a fluid centre column — with Flexbox, and when would you reach for CSS Grid instead?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Nest two flex containers: an outer column for header, body and footer with min-height: 100vh, and an inner row where each sidebar is flex: 0 0 240px and the centre is flex: 1. Grid is better once the layout is genuinely two-dimensional or must rearrange at breakpoints.

open as a page

In an app shell built from nested flex-direction: column containers, a panel with overflow-y: auto never scrolls — the whole page grows instead. What causes this and how do you fix it?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Each column flex item defaults to min-height: auto, so it cannot be shorter than its content and grows instead of bounding the scroller. Add min-height: 0 (or a non-visible overflow) on every flex item between the height-constrained ancestor and the scrolling panel.

open as a page

A 240px-wide logo in a flex toolbar gets squeezed on narrow screens even though its width is set, and the widest item loses the most space. Explain what the shrink algorithm is doing and how you would fix the logo.

level: seniorimportance: should knowfreq 48%

basics

~20 s

Flex items shrink by default because flex-shrink is 1, and the deficit is split in proportion to flex-shrink multiplied by each item's base size, so wider items give up more. Pin the logo with flex-shrink: 0, or flex: 0 0 240px.

open as a page

In a wrapped flex row of cards where each card is flex: 1 1 240px, the cards on the final row render much wider than the rows above. Why does that happen, and how do you get consistent card widths?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Flexbox distributes free space per flex line, not across the whole container. The last line holds fewer cards, so each one grows more. Cap the growth with flex-grow: 0 or a max-width, or switch to a two-dimensional layout.

open as a page

How does a child with position: absolute behave inside a display: flex container — is it still a flex item?

level: middleimportance: nice to knowfreq 27%

basics

~20 s

No. An absolutely positioned child is out of flow, so it is not a flex item: it takes no space, is ignored by free-space distribution, and flex-grow, flex-shrink, flex-basis and order do nothing to it. Alignment still sets its static position.

open as a page