In CSS Flexbox, what happens to a child's display, float and vertical-align once its parent becomes a flex container?
answer
- the child's own box changes type
- inline-level behaviour is switched off
- float has nothing to float against
- margins stay stubbornly separate
- whitespace between items generates nothing
basics
~10 sFlex 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.
solid answer
~50 sBecoming a flex item changes the child's own box, not just where it is placed. The child's display value is **blockified** — `inline` and `inline-block` compute to `block`, `inline-flex` to `flex` — so it is no longer an inline-level box. Everything that only makes sense for inline-level or floated boxes therefore stops applying: `float` and `clear` have no effect on a flex item, and `vertical-align` is ignored. Margins on flex items never collapse, not between adjacent items and not with the container's own margins, so two facing `20px` margins give `40px` rather than `20px`. Whitespace-only text between items does not generate an item at all, which is why the mystery gaps between `inline-block` boxes disappear the moment the parent becomes a flex container — and why non-whitespace bare text does get wrapped in an anonymous flex item you cannot select.
code
html · 8 lines<style>
.row { display: flex; }
.row > span { display: inline-block; float: left; vertical-align: middle; margin: 20px; }
</style>
<div class="row">
<span>one</span>
<span>two</span>
</div>go deeper
Know that inside a flex container the old tools stop working: float, clear and vertical-align on the children have no effect, and inline-block children compute to block.
State the general rule — flex items are blockified — and derive the specifics from it, including that item margins never collapse and that whitespace between items generates no item.
Show migration judgment: strip dormant float and vertical-align declarations when converting a layout, since they lie in wait and reactivate the moment a media or container query removes display: flex.
Own the risk this creates at scale. Where flex containers are toggled by breakpoints, the codebase needs a standing rule that children carry no flow-era declarations, otherwise every direction switch is an unreviewable behavioural change.
## Flex items get a new box type When an element becomes a flex container, each of its direct children that generates a box becomes a flex item — and the item's own display type is **blockified**. Blockification means the computed value of `display` is coerced to its block-level equivalent: - `inline` becomes `block` - `inline-block` becomes `block` - `inline-flex` becomes `flex` - `inline-grid` becomes `grid` - `inline-table` becomes `table` This is a computed-value change, so devtools will show you `block` even though your stylesheet says `inline-block`. Nothing about the element's *content* changes — text inside it still lays out inline, as it always did. Only the item's participation as a box has changed. ## What stops working, and why Once a child is a blockified flex item, the properties that exist only to position boxes in normal flow or in a line box become meaningless, and the specification says so explicitly: - **`float` and `clear` have no effect.** A flex item is placed by the flex algorithm; it is not taken out of flow and there is no line box for it to float against. `float: left` on a flex item is dead code. - **`vertical-align` has no effect.** It aligns inline-level boxes within a line box, and a flex item is neither. Cross-axis alignment is what replaces it. - **Margins do not collapse.** Flex items live in a flex formatting context, so adjacent margins are not merged and a child's margin never escapes through the container's edge. Two stacked items with `margin: 20px 0` sit `40px` apart, not `20px` — one of the pleasant differences from block layout, and one of the first things to check when a converted layout suddenly has more spacing than before. ```css .row { display: flex; } .row > span { float: left; /* ignored */ vertical-align: middle; /* ignored */ display: inline-block; /* computes to block */ } ``` ## The whitespace gaps that vanish A layout built from `inline-block` boxes has a famous quirk: newlines between the elements in the markup render as spaces, producing gaps nobody asked for. Switch the parent to `display: flex` and those gaps disappear. The reason is a rule about what becomes an item. A run of text directly inside a flex container is wrapped in an **anonymous flex item** — except when the run is entirely whitespace, in which case no item is generated at all. Combined with blockification, which takes the children out of any line box, there is simply nothing left for inter-word spacing to apply to. The flip side is worth knowing: non-whitespace bare text *does* become an anonymous flex item. It participates in the layout, taking a slot on the main axis, but it has no element, so you cannot select it, give it a class, or set `flex` on it. If a stray label appears to be shoving your buttons around, unwrapped text in the container is a likely culprit, and the fix is to wrap it in an element. ## Children that are not items Two display values behave specially: - **`display: none`** generates no box at all, so the child is neither an item nor anything else. - **`display: contents`** generates no box for the element itself, and its *children* become the flex items instead. This is occasionally useful for flattening a wrapper without changing the markup, but it also means the wrapper's own styling has nowhere to land. ## Why interviewers ask this It separates people who have memorised a few property names from people who understand that Flexbox replaces the layout mode of the children rather than layering something on top of it. The strongest version of the answer states the general rule — becoming a flex item blockifies the child and switches off flow- and inline-specific properties — and then derives the individual facts from it, instead of reciting a list. If you can go on to explain the vanishing whitespace gaps from the anonymous-item rule, you have shown you understand where flex items come from as well as how they behave. ## Practical consequences When migrating an old float- or inline-block-based layout to Flexbox, the leftover `float`, `clear` and `vertical-align` declarations on the children are not harmful, but they are misleading: a future reader cannot tell whether they matter. Delete them with the migration. Conversely, if someone later removes `display: flex` from the parent — behind a media query, say — every one of those dormant declarations wakes up at once, and the layout collapses in a way that looks unrelated to the change that caused it.
- Why do the gaps between inline-block boxes disappear once their parent becomes a flex container?Because whitespace-only text between the children does not generate a flex item, and the children themselves are blockified out of any line box. The gap was inter-word spacing in the parent's inline flow; with no line box and no whitespace item, there is nothing left to produce it.
- What happens to a bare text node placed directly inside a flex container?If it contains anything other than whitespace it is wrapped in an anonymous flex item and takes part in the layout like any other item. Because there is no element, you cannot select it or set flex properties on it — the only fix is to wrap the text in an element of your own.
- Does display: contents on a child change which boxes are the flex items?Yes. The element generates no box of its own, so it is not an item; its children are promoted and become the flex items instead. That flattens a wrapper without editing markup, at the cost of the wrapper having no box left to style.
saying these in an interview costs you the question
- Uses float to position boxes inside a flex container
- Reaches for vertical-align to centre a flex item
- Expects adjacent flex item margins to collapse
- Thinks inline children stay inline-level inside a flex container
- Blames flex for gaps that come from markup whitespace