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?
answer
- One axis, two competing size properties
- Basis outranks width on the main axis
- auto is a redirect, not a size
- Then width auto falls back to content
- Min and max clamp after flexing
basics
~20 sflex-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.
solid answer
~40 sOn the main axis, `flex-basis` is the sizing property that counts, and `width` is only a fallback. With `width: 200px; flex-basis: 100px` in a row, the flex algorithm starts from a base size of 100px and then grows or shrinks from there — the 200px is ignored. The keyword `auto` is the hinge: `flex-basis: auto` literally means "go and look at my main-size property", so in a row it defers to `width`, and in a column it defers to `height`. Only when that property is also `auto` does the item fall back to content sizing, roughly its max-content size. Note that `min-width` and `max-width` still clamp the result afterwards — they apply after the flex algorithm has resolved a size, so they can override both `width` and `flex-basis`.
code
css · 15 lines.row { display: flex; width: 600px; }
.row .basis-wins {
width: 200px;
flex-basis: 100px; /* base size is 100px */
flex-grow: 0;
flex-shrink: 0;
}
.row .auto-defers {
width: 200px;
flex-basis: auto; /* base size is 200px, taken from width */
flex-grow: 0;
flex-shrink: 0;
}go deeper
Remember the headline: on the main axis flex-basis beats width, and flex-basis: auto is the reason width usually seems to work. Say plainly which value a given pair of declarations produces.
Walk through the auto redirect chain — basis auto to width, width auto to content size — and explain that a definite basis is only the starting point before grow and shrink run.
Diagnose the real-world version: an item with flex: 1 whose width is being ignored, or a flex-basis clamped afterwards by min-width or max-width. Show you would express fixed tracks as flex: 0 0 <length> instead of width.
Have a position on the sizing convention a design system should encode — where flex-basis with border-box is the contract for component authors, and where a grid track definition expresses fixed and fluid columns more honestly than per-item flex bases.
## Two properties, one axis A flex item can be told its main-axis size by two different properties, and they do not have equal standing. The flex layout algorithm computes a **flex base size** for each item, and it takes that from `flex-basis`. `width` (in a row) or `height` (in a column) only gets consulted when `flex-basis` hands the decision over. ```css .row { display: flex; } .row .item { width: 200px; /* ignored on the main axis */ flex-basis: 100px; /* the flex base size */ } ``` So the answer to the interview question is: 100px. The `width` is not deleted — it still applies on the cross axis if the direction flips to `column`, and it still participates in intrinsic sizing calculations elsewhere — but for main-axis flex sizing it loses. ## The auto keyword is a redirect, not a size The reason the rule confuses people is that `flex-basis`'s initial value is `auto`, and `auto` does not mean "content size". It means *"use my main size property"*: 1. `flex-basis: auto` in a row → look at `width`. 2. If `width` is also `auto` → fall back to content sizing (roughly the item's max-content size, its natural width with no wrapping). 3. In a `column` container, the same chain runs through `height` instead. That two-step is why `width: 200px` appears to work on flex items most of the time — not because `width` beat `flex-basis`, but because the default `flex-basis: auto` delegated to it. ```css .a { flex-basis: auto; width: 200px; } /* base size 200px, via width */ .b { flex-basis: auto; } /* base size = content size */ .c { flex-basis: 0; width: 200px; } /* base size 0, width ignored */ ``` Case `.c` is the everyday one: `flex: 1` expands to `flex: 1 1 0%`, so writing `flex: 1` silently makes any `width` on that item irrelevant to the main axis. Engineers who add `flex: 1` and then wonder why their `width: 200px` "stopped working" have hit exactly this. ## The base size is a starting point, not a final size Even a definite `flex-basis` is only where the item *starts*. After computing every item's flex base size, the algorithm clamps each one by its own min and max constraints to get a **hypothetical main size**, sums those, compares the total against the container's inner main size, and then distributes the surplus by `flex-grow` or the deficit by `flex-shrink`. An item with `flex-basis: 100px` in a container with room to spare ends up wider than 100px if it has a non-zero grow factor. If you want `flex-basis` to be the final answer, you have to turn the flexing off: ```css .sidebar { flex: 0 0 240px; } /* start at 240px, never grow, never shrink */ ``` ## What still overrides flex-basis `min-width` and `max-width` (and their block-axis counterparts) are applied *after* flexing and clamp the used size. A `max-width: 150px` will cap an item whose flex-basis and grow factor wanted 300px; a `min-width: 320px` will floor an item that flexing wanted to squeeze to 200px. This is why "my flex-basis is ignored" is often really "a min or max constraint clamped it afterwards". ## Percentages and box-sizing A percentage `flex-basis` resolves against the flex container's inner main size — `flex-basis: 50%` in a 600px-wide row is 300px before grow and shrink run. When the container's main size is indefinite, that percentage cannot resolve and the item falls back to content-based sizing. `flex-basis` also respects `box-sizing`. Under the default `content-box`, `flex-basis: 100px` means 100px of *content*, with padding and border added on top, so two items with equal bases but different padding are not equal on screen. Setting `box-sizing: border-box` makes `flex-basis` include padding and border, which is usually what people intend. ## How to answer this cleanly in an interview Say three things and stop: `flex-basis` wins on the main axis; `auto` is a redirect to `width`/`height` and then to content; min/max constraints clamp the result afterwards. Then add the practical consequence — `flex: 1` sets `flex-basis: 0`, so it neutralises `width` on that axis, and if you want a fixed track you should write `flex: 0 0 <length>` rather than reaching for `width` and hoping.
- Why does a width on an item with flex: 1 appear to have no effect?`flex: 1` expands to `flex: 1 1 0%`, so `flex-basis` is a definite `0` and no longer defers to `width`. The item starts from zero and is sized entirely by its share of the container. If you want the declared size honoured, write `flex: 0 0 200px`, or set `flex-basis: auto` alongside the grow factor.
- What does flex-basis: 50% resolve against, and what happens if that can't be resolved?It resolves against the flex container's inner main size — the content box along the main axis — so 50% of a 600px row is a 300px base. If the container's main size is indefinite, the percentage has nothing to resolve against and the item falls back to content-based sizing instead.
- If flex-basis wins on the main axis, does width do anything at all on a flex item?Yes. In a `row` container `width` is the main size, so it is what `flex-basis: auto` defers to; in a `column` container `width` is the cross size and applies directly, untouched by flex-basis. `min-width` and `max-width` also still clamp the used size after flexing in either direction.
saying these in an interview costs you the question
- Says width always beats flex-basis on flex items
- Thinks flex-basis: auto means content size, ignoring width
- Believes flex-basis is the final size rather than a starting point
- Claims flex-basis applies to height in a row container
- Forgets min-width and max-width clamp after flexing