skip to content

flex-grow, flex-shrink, and flex-basis

How free space is actually distributed: basis sets the hypothetical size, grow shares the surplus, shrink absorbs the deficit weighted by basis. "What does flex: 1 mean" is close to a guaranteed frontend interview question.

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

questions

4

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%

answer

  1. Three longhands hidden behind one word
  2. Order is grow, shrink, basis
  3. One number also rewrites the basis
  4. flex: 1 is 1 1 0%
  5. Item default equals flex: initial

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.

solid answer

~40 s

`flex` is shorthand for `flex-grow flex-shrink flex-basis`. A single unitless number sets grow and *resets basis to zero*, so `flex: 1` means `1 1 0%`: the item's own content size is discarded and it takes an equal share of the container's main size. `flex: auto` is `1 1 auto` — it grows and shrinks, but starts from its `width` or its content. `flex: none` is `0 0 auto`, completely inflexible and sized by content or `width`. `flex: initial` is `0 1 auto`, which is also what a flex item gets with no `flex` declaration at all: it will not grow into free space, but it will shrink when the line overflows. The distinction people actually trip on is `flex: 1` versus `flex: auto` — equal-sized items versus content-proportional items.

code

css · 5 lines
css
.row { display: flex; }
.row .equal    { flex: 1; }       /* 1 1 0%   - equal sizes */
.row .natural  { flex: auto; }    /* 1 1 auto - content-proportional */
.row .rigid    { flex: none; }    /* 0 0 auto - never flexes */
.row .standard { flex: initial; } /* 0 1 auto - the item default */

go deeper

for a junior

Memorise the order grow, shrink, basis, and the four expansions. Be able to say out loud that flex: 1 means 1 1 0% and is the usual way to get equal-width columns.

for a middle

Explain why the single-number form resets flex-basis to zero, and demonstrate the resulting difference between flex: 1 and flex-grow: 1 on items with unequal content. Know that an untouched item is 0 1 auto.

for a senior

Show you reach for the right form deliberately in real layouts: flex: none or 0 0 <length> to pin a sidebar, flex: auto when natural proportions matter, and be ready to explain why padding makes flex: 1 items unequal under content-box.

for a principal

Argue for an explicit three-value convention in a shared codebase, since relying on shorthand defaults is a repeated source of review churn, and be able to say where a flex sizing convention should give way to grid track sizing instead.

## The three longhands Every flex item has three sizing longhands that the `flex` shorthand sets together: - **`flex-grow`** — a unitless proportion saying how much of the container's *leftover* main-axis space this item absorbs. `0` means "take none of it". - **`flex-shrink`** — a unitless proportion saying how much of a *deficit* this item absorbs when the items together are too big for the line. `0` means "never shrink me". - **`flex-basis`** — the item's starting size on the main axis, before any growing or shrinking. It is a length, a percentage, or the keyword `auto`. "Main axis" means the direction items flow: horizontal in the default `flex-direction: row`, vertical in `column`. So `flex-basis` is a starting width in a row and a starting height in a column. ## What the shorthand does with one value This is the part that surprises people. When you write `flex` with a single unitless number, the shorthand sets *all three* longhands, not just grow: ```css .item { flex: 2; } /* equivalent to */ .item { flex-grow: 2; flex-shrink: 1; flex-basis: 0%; } ``` The omitted `flex-basis` in the shorthand defaults to `0%`, **not** to `auto`. That zero is what makes `flex: 1` the "equal columns" idiom: if every item starts from a base size of zero, then *all* of the container's main size is free space, and items with equal grow factors split it equally regardless of how much text each contains. That also means `flex: 1` and `flex-grow: 1` are not interchangeable. `flex-grow: 1` on its own leaves `flex-basis` at its initial `auto`, so items start at their content size and only the *leftover* is shared equally — the items end up unequal. ```css .a > * { flex: 1; } /* base 0 -> equal widths */ .b > * { flex-grow: 1; } /* base auto -> content size + equal share of leftovers */ ``` ## The four named forms | Shorthand | Expands to | Behaviour | | --- | --- | --- | | `flex: 1` (any single number `n`) | `n 1 0%` | Fully flexible from a zero base; equal grow factors give equal sizes | | `flex: auto` | `1 1 auto` | Grows and shrinks, but starts from `width`/content, so bigger content stays bigger | | `flex: none` | `0 0 auto` | Completely inflexible; sized by `width` or content and left alone | | `flex: initial` | `0 1 auto` | Won't grow into free space, but will shrink to avoid overflow | `flex: initial` is worth memorising for a second reason: it is the **default state of every flex item**. An item you never touched behaves as `flex-grow: 0; flex-shrink: 1; flex-basis: auto`. That single fact explains two of the most common flex surprises at once: items don't fill the container by default (grow is `0`), and items *do* get squeezed below their declared `width` by default (shrink is `1`). You can also write two values. `flex: 1 200px` means `flex-grow: 1; flex-shrink: 1; flex-basis: 200px` — a number plus a length sets grow and basis and leaves shrink at `1`. Two numbers, `flex: 1 0`, set grow and shrink and reset basis to `0%`. ## Why the zero basis is spelled `0%` The specification defines the one-value form as resetting `flex-basis` to zero; browsers serialise it as `0%`. In a row-direction container the difference between `0` and `0%` is not observable for the sizing math — both mean "start from nothing" — so treat `flex: 1` as `1 1 0` when reasoning about layout. One detail that does matter: `flex-basis` obeys `box-sizing` like any other sizing property. Under the default `content-box`, `flex: 1` gives a *content* base of zero, and the item's padding and border are still added on top, so "equal" items are only truly equal when their padding and borders match — or when the container sets `box-sizing: border-box`. ## Choosing between them - Want columns that end up the same size no matter what is inside them? `flex: 1`. - Want items to keep their natural proportions but still fill the row? `flex: auto`. - Want a logo, an icon, or a fixed sidebar that neither stretches nor gets squeezed? `flex: none` (or `flex: 0 0 240px` to pin an exact size). - Want the default? Write nothing; that is `flex: initial`. When you need something the named forms don't cover, spell out all three values — `flex: 0 1 320px` reads unambiguously and is what most style guides prefer over remembering shorthand defaults.

  • If flex: 1 and flex-grow: 1 both make items expand, why do they produce different widths?
    Because the shorthand also resets `flex-basis`. `flex: 1` is `1 1 0%`, so every item starts at zero and the whole container is free space split equally. `flex-grow: 1` leaves `flex-basis: auto`, so each item starts at its content or `width` and only the leftover is split equally — items with more content stay wider.
  • What does the two-value form flex: 1 200px mean?
    A number followed by a length sets `flex-grow: 1` and `flex-basis: 200px`, leaving `flex-shrink` at its default `1`. So the item starts at 200px, grows into free space, and is still allowed to shrink if the line overflows. Two *numbers*, like `flex: 1 0`, set grow and shrink instead and reset basis to zero.
  • Why do items not fill their flex container until you add flex: 1?
    Because the default item state is `flex: initial`, i.e. `flex-grow: 0`. Growing into leftover space is opt-in. Shrinking is not: `flex-shrink` defaults to `1`, which is why an untouched item can end up narrower than its declared `width` but never wider.

Think of flex-basis as the size each item asks for, flex-grow as its share of a bonus payout, and flex-shrink as its share of a budget cut.

saying these in an interview costs you the question

  • Says flex: 1 only sets flex-grow and leaves basis alone
  • Thinks flex: 1 and flex: auto are the same thing
  • Claims the 1 in flex: 1 is a fraction unit like grid's fr
  • Says flex: auto is the default state of a flex item
  • Believes items grow to fill the container by default

context

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

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