Command Palette

Search for a command to run...

Hectal
PHASE 7Intermediate ~27 min· topic 4 of 5

Topic 7.4

Wrapping and Gaps

In one line

flex-wrap: wrap lets items break onto new lines instead of shrinking, gap puts fixed space between items and lines without touching the outer edges, and order changes only the visual position of an item, never its reading or Tab order.

Think of it like this

Writing on lined paper. When a word doesn't fit at the end of a line, you don't squash it: you start a new line. That's flex-wrap: wrap. The space you leave between words and between lines is the gap. And if you number your sentences "read this one first", the paper still has them in the order you wrote them; only a reader who follows the numbers sees a different order. That's order.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

`flex-wrap`
Whether items may break onto new lines: nowrap (default), wrap or wrap-reverse.
Flex line
One row (or column) of items in a flex container. Wrapping creates several lines.
Multi-line container
A flex container with flex-wrap: wrap or wrap-reverse, even if it currently has one line.
`flex-flow`
A shorthand for flex-direction and flex-wrap together, like flex-flow: column wrap.
`gap`
Space between items and between lines. Shorthand for row-gap and column-gap.
`row-gap` / `column-gap`
The space between lines, and the space between items in a line (for a row container).
`order`
An integer that changes an item's visual position. Lower numbers come first. Default 0.
Visual order vs DOM order
What the eye sees, versus the order in the HTML, which keyboards and screen readers follow.

Step by step

01See what nowrap does

Five 60px items in a 200px row need 300px. With the default nowrap they stay on one line and shrink to 40px each. Add a long word and they would overflow instead.

style.csswhole filecss
.row {
  display: flex;
  width: 200px; /* 5 x 60 = 300px of items */
}
.row > * { flex-basis: 60px; }

02Let the items wrap

With flex-wrap: wrap, three items fit on the first line (180px) and the fourth starts line 2. The items keep their 60px; the 20px left on each line is free space for justify-content.

style.csswhole filecss
.row {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
}
Let the items wrapdiagram
Rendering diagram…

03Add gaps

gap: 10px adds 10px between items in a line and 10px between lines. Three items plus two gaps is 60 + 10 + 60 + 10 + 60 = 200px: still a perfect fit. Nothing is added at the edges.

style.csswhole filecss
.row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;          /* or: row-gap: 10px; column-gap: 10px; */
}

04Build a responsive row without media queries

Give items a basis and let them grow: flex: 1 1 150px. On a wide screen four fit per line; on a phone one. They grow to fill each line.

style.csswhole filecss
.cards { display: flex; flex-wrap: wrap; gap: 16px; }
.cards > * { flex: 1 1 150px; }

05Reorder with care

order: -1 moves an item to the start of the line, visually. A keyboard user pressing Tab still visits the items in HTML order, so use it for decoration, not for things people read or press in sequence.

style.csswhole filecss
.featured { order: -1; } /* shown first, still read where it is in the HTML */

Try it yourself

  1. 1

    Predict the wrap point

    In the first example, change the item basis to 70px. Predict how many items fit on the first line of the wrap row, and the nowrap widths. (Two per line: 140px fits, 210px doesn't. In the nowrap row, 350px must fit into 200px, so each item loses 30px and ends at 40px again.)

  2. 2

    Break the perfect fit

    In the gap example, change .same to gap: 12px. Predict where item 3 goes. (60 + 12 + 60 + 12 + 60 = 204px is more than 200, so item 3 wraps to line 2.)

  3. 3

    Center the last line

    In the card example, change the cards to flex: 0 1 110px and add justify-content: center to .cards. Predict what happens to the last line. (The cards stop growing, keep 110px plus padding, and the last line is centred.)

Code & diagrams

nowrap, wrap and wrap-reverse New tab

`nowrap` squeezes all five onto one line (300px into 200px, so each loses 20px). `wrap` keeps 60px and moves items 4 and 5 to a second line. `wrap-reverse` puts the first line at the bottom.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

nowrap: widths 40,40,40,40,40 | tops 0,0,0,0,0
wrap: widths 60,60,60,60,60 | tops 0,0,0,30,30
wrap-reverse: widths 60,60,60,60,60 | tops 30,30,30,0,0
gap, row-gap and column-gap New tab

With `gap: 10px`, three items and two gaps fill exactly 200px, and line 2 starts at 30 + 10 = 40. With `gap: 20px 5px`, the first value is the row gap (between lines) and the second the column gap (between items).

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

same: x 0,70,140 | item 4 top 40 | row-gap 10px
split: x 0,65,130 | item 4 top 50 | row-gap 20px
order changes what you see, not what you Tab through New tab

C (`order: -1`) jumps to the front, B (`order: 2`) to the back; A and D share `order: 0` and keep their HTML order. Click A and press Tab a few times: focus goes A, B, C, D, jumping around the screen.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

HTML and Tab order: A B C D
Visual order:       C A D B
order values: 0, 2, -1, 0
Responsive cards with wrap and a basis New tab

Make the preview wider and narrower: the number of cards per line changes on its own. The last line's cards grow to fill their line, so they can be wider than the others. Grid's `auto-fill` (Topic 8.2) keeps every column the same.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Forget to turn on wrapping

In the card example, remove flex-wrap: wrap and make the preview narrow.

terminal
$ Preview
── what you'll see ──
All five cards squeeze onto one line, each about as wide as its word, and the row runs past the right edge.

Break #2

Use margins instead of gap

Replace gap: 10px in the .same row with .same b { margin-right: 10px; }.

terminal
$ Console
── what you'll see ──
same: x 0,70,0 | item 4 top 30 | row-gap normal

Myth vs fact

Myth

gap only works in Grid.

Fact

gap, row-gap and column-gap have worked in Flexbox in every major browser since 2021 (Safari 14.1 was the last).

Myth

Wrapped flex items line up in columns.

Fact

Every flex line is sized on its own, so items on different lines only line up by accident. For aligned columns, use Grid.

Myth

order is a good way to fix the order of a page.

Fact

It changes only what you see. Keyboard and screen-reader users still get the HTML order, so meaningful order must be fixed in the HTML.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Feature detection for flex gap was impossible with @supports (gap: 1px), because gap already existed for Grid; that's why the negative-margin hack lived on long after Grid shipped. Today you can use gap in Flexbox without a fallback.

  • ▸

    Percentage gap values in Flexbox resolve against the container's content box; in an auto-height column container a percentage row gap can't resolve and is treated as 0.

  • ▸

    order also affects painting order (items with a later order paint on top when they overlap) and is how z-index stacking ties are broken inside flex containers. Note that flex items can use z-index without position, and it creates a stacking context (Phase 6, Topic 6.4).

  • ▸

    flex-wrap: wrap with flex-direction: column needs a definite height to wrap into, and browsers historically mis-sized the container's width in that case (it doesn't grow to fit extra columns). Grid with grid-auto-flow: column is more reliable for column-wise flow.

Remember this

  1. 1

    By default, flex-wrap is nowrap: every item stays on one line, and if they don't fit they shrink (Topic 7.3). If they can't shrink any further, they overflow the container. flex-wrap: wrap allows a multi-line flex container: when the next item doesn't fit, it moves to a new flex line. Each line is laid out on its own: growing, shrinking and justify-content happen per line, so items on different lines don't line up with each other.

  2. 2

    flex-wrap: wrap-reverse wraps too, but stacks the lines in the opposite direction on the cross axis: the first line sits at the bottom (in a row). The shorthand **flex-flow** sets flex-direction and flex-wrap together: flex-flow: row wrap.

  3. 3

    **gap sets space between** items and between lines, never at the outer edges. gap: 16px sets both; gap: 8px 16px sets row-gap (between lines) first and column-gap (between items in a line) second. Before gap worked in Flexbox (all major browsers since 2021), people used margins on every item and a negative margin on the container to cancel the edges. gap is simpler: the space is counted when items are sized, so flex: 1 items still fill the line exactly.

  4. 4

    Wrapping decides line breaks from each item's hypothetical size (its basis, clamped by min and max). flex: 1 1 150px with flex-wrap: wrap is a classic responsive trick: items are at least about 150px, as many fit per line as possible, and then they grow to fill the line. No media query needed. The catch: the last line grows too, so a lone last item can become very wide. When you need every column to line up, use Grid (Topic 8.2, auto-fill).

  5. 5

    **order** is an integer on an item (default 0). Items are laid out in ascending order, and items with the same value keep their HTML order. Negative values move an item before all the 0 items. order changes only the visual order. Screen readers read the HTML order and the Tab key moves focus in HTML order, so order must never change the meaning of the content. Use it for small visual swaps, for example putting an image first on narrow screens.

Explain it without notes

01

What is the difference between flex-wrap: nowrap and wrap when items don't fit?

02

Why is gap better than margins for spacing flex items?

03

What does order change, and what doesn't it change?

04

How can you make a responsive row of cards with Flexbox and no media queries, and what is its weakness?

Practice

01

Make a list of tags (<span class="tag">) wrap onto new lines with 8px between tags and 6px between lines.

02

Write CSS for a row of items that wraps, with 16px gaps, where each item is at least 200px and grows to fill the line.

03

A product card has <img> then <h2> in the HTML. Show the heading above the image visually. Is order a good idea here?

Trade-offs

  • ↔

    Flex wrapping adapts to content and needs no breakpoints, but you give up aligned columns. Grid adds alignment across lines at the cost of deciding track sizes.

  • ↔

    order saves duplicating HTML for different layouts, but every use creates a mismatch between what is seen and what is read, so keep it for decoration.

Done when you can

  • I can make items wrap and explain what nowrap does instead.

  • I can use gap, row-gap and column-gap, and know gap: a b is row then column.

  • I can predict where items wrap when gaps are included.

  • I can build a responsive wrapping row with flex: 1 1 <size>.

  • I can use order and explain why it doesn't change Tab order.