skip to content

Wrapping, Order, and Multi-line

flex-wrap turns one flex line into several, which changes how cross-axis alignment behaves and enables responsive card rows with no media queries. Also covers the order property and the accessibility cost of visual reordering.

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

questions

4

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%

answer

  1. single line is the default
  2. shrink happens before overflow
  3. nowrap is the initial value
  4. wrap creates additional flex lines
  5. flex-flow bundles direction and wrap

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.

solid answer

~40 s

The initial value is `nowrap`, which means a flex container has exactly one flex line no matter how many items it holds. When the items' combined base size exceeds the container, they do not wrap — instead `flex-shrink` (default `1`) shrinks them proportionally, and if they still cannot fit, the line overflows the container's edge. `flex-wrap: wrap` changes that: the container collects items into as many flex lines as it needs, stacking the extra lines along the cross axis. `flex-wrap: wrap-reverse` does the same but swaps cross-start and cross-end so the lines stack in the opposite direction. `flex-wrap` is a container property, not an item property, and `flex-flow` is the shorthand for `flex-direction` and `flex-wrap` together, so `flex-flow: row wrap` is the common one-liner.

code

css · 16 lines
css
.no-wrap {
  display: flex;
  width: 600px;
}

.wrapping {
  display: flex;
  flex-flow: row wrap;
  gap: 16px;
  width: 600px;
}

.no-wrap > .card,
.wrapping > .card {
  width: 200px;
}

go deeper

for a junior

Be able to say that the default is nowrap, that items shrink and then overflow, and that flex-wrap: wrap is what creates extra lines. Know flex-wrap belongs on the container.

for a middle

Explain the mechanics: base sizes are summed, negative free space is removed via flex-shrink, and shrinking stops at each item's automatic minimum size. Describe flex-flow and what wrap-reverse flips.

for a senior

Show judgment about when wrapping is the right responsive tool versus a breakpoint, and be ready to diagnose a container where wrap appears to do nothing, such as a column container with an unconstrained height.

for a principal

Frame it as a policy decision: intrinsically responsive wrapping reduces breakpoint count and CSS surface area, but it gives up precise control over line composition. Be able to argue when a team should standardise on wrapping versus explicit breakpoints.

## One line unless you say otherwise A flex container lays its items out along a **main axis** (horizontal for `flex-direction: row`, vertical for `column`) and aligns them along the perpendicular **cross axis**. The `flex-wrap` property decides whether that main axis may be split into more than one *flex line*. Its initial value is `nowrap`, so by default a flex container is single-line: every child sits on one line, however many children there are and however narrow the container is. This catches people out because the layout does not visibly "break" when it runs out of room. It quietly compresses. ## Shrink first, overflow second Each flex item has a **flex-basis**, its starting size along the main axis (`auto` by default, which falls back to the item's `width`/`height` or its content size). The container adds up those base sizes. If the total is larger than the container, the container has negative free space, and it removes that space using each item's `flex-shrink` factor, which is `1` by default. So five 200px items in a 600px container do not wrap — they each become 120px. ```css .row { display: flex; /* flex-wrap is nowrap here */ width: 600px; } .row > div { width: 200px; /* five of these render 120px wide */ } ``` Shrinking has a floor. An item will not shrink below its automatic minimum size, which is roughly its `min-content` size — the width of its longest unbreakable word, or an image's intrinsic width. Once every item is at that floor and the total is still too big, the line overflows the container's content box and, depending on `overflow`, either spills visibly or gets clipped. ## Turning wrapping on ```css .cards { display: flex; flex-wrap: wrap; gap: 1rem; } ``` With `wrap`, the container walks the items in order and starts a new flex line whenever the next item would not fit on the current one. Each resulting line is then laid out largely independently: `flex-grow` and `flex-shrink` are resolved per line, and each line's cross size is driven by the tallest item on it. Multiple lines are then positioned along the cross axis of the container. Two consequences worth internalising: wrapping happens **instead of** shrinking below the natural break point (the browser does not try to shrink items to keep them on one line once wrapping is allowed), and a wrapped container can be taller than any single item because it now stacks lines. ## wrap-reverse `flex-wrap: wrap-reverse` wraps and then flips the cross axis: cross-start and cross-end swap places. In a `row wrap-reverse` container the *first* line ends up at the bottom and subsequent lines stack upward. The order of items **within** each line is unchanged — that is `flex-direction: row-reverse`'s job. A practical side effect is that any cross-axis alignment keyword you already wrote, such as `align-items: flex-start`, now points the other way. ## The flex-flow shorthand `flex-flow` sets `flex-direction` and `flex-wrap` in one declaration, in either order: `flex-flow: row wrap`, `flex-flow: wrap column`, `flex-flow: column-reverse wrap-reverse`. Omitted parts reset to their initial values, so `flex-flow: wrap` also resets direction to `row`. It is a convenience, not a different mechanism. ## Wrapping a column container `flex-wrap` works on the main axis, whatever that axis is. In a `flex-direction: column` container with `flex-wrap: wrap`, items wrap into **additional columns** once the container's height is exhausted — which only happens if the container has a constrained height. A column container with `height: auto` grows forever and will never wrap, which is a common source of "why is wrap doing nothing?". ## Things that commonly go wrong - Putting `flex-wrap` on the item instead of the container: it is a container property and has no effect on a child. - Expecting `overflow: hidden` or `text-overflow: ellipsis` to substitute for wrapping — they hide the symptom on one line, they do not create a second line. - Assuming that because content overflowed, `flex-shrink` "didn't work". It usually did work, right down to the items' minimum sizes. - Reaching for media queries to switch a row to a column, when `flex-wrap: wrap` plus a sensible `flex-basis` often gives a responsive row for free.

  • What exactly does flex-wrap: wrap-reverse change compared to wrap?
    It still produces multiple flex lines, but it swaps cross-start and cross-end, so in a row container the first line renders at the bottom and later lines stack upward. The order of items within each line is untouched — reversing that is `flex-direction: row-reverse`. Any cross-axis alignment you wrote, such as `align-items: flex-start`, now resolves to the opposite physical edge.
  • Does flex-wrap: wrap do anything useful on a flex-direction: column container?
    Yes, but only when the container's height is constrained. Wrapping happens on the main axis, which is vertical for a column container, so items wrap into extra columns once the height runs out. With `height: auto` the container simply grows and no wrap ever occurs, which is why `column` plus `wrap` so often looks like a no-op.
  • If wrapping is off and the items still overflow, what stopped flex-shrink from fitting them?
    Shrinking has a lower bound: an item will not go below its automatic minimum size, roughly its `min-content` size — the longest unbreakable word, or an image's intrinsic width. Once every item is pinned at that floor, the remaining excess has nowhere to go and the single flex line overflows the container's content box.

saying these in an interview costs you the question

  • Thinks flex items wrap automatically when space runs out
  • Believes overflow proves flex-shrink was not applied
  • Puts flex-wrap on the item rather than the container
  • Assumes nowrap also prevents items from shrinking
  • Thinks flex-flow is shorthand for flex-grow and flex-shrink

context

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

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

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