Lesson 05: Wrapping into real layouts
Lesson objectives:
- Use
flex-wrap: wrapso items flow onto multiple rows instead of overflowing.- Space items with
gapinstead of fiddly margins.- Build a real, responsive nav and card row using everything from this course.
Prerequisites: Lessons 01-04 (axes, alignment,
flex-direction,flex-grow) | Previous << 04
Six cards, one row, and a squished mess
You have a row of cards. On a wide screen they fit. On a narrow one they either overflow the container or get crushed thin, because by default a flex line refuses to break — it keeps everything on one row no matter what. That single default is why so many "responsive" card layouts fall apart. The fix is one property to allow wrapping and one to space the result. Then we put the whole course together and build the layouts you actually ship.
Explanation
By default flex-wrap is nowrap, which means a set of items too wide for the container will overflow it1. That is the crushed-or-overflowing behavior. To let items break onto new lines, set flex-wrap: wrap on the container — items then wrap onto new lines when they run out of room1.
Wrapping alone can leave items jammed edge to edge. The clean way to space them is the gap property on the container: it creates fixed space between adjacent flex items, and it is a shorthand for row-gap and column-gap1. Crucially, gap puts space between items only — not on the outer edges — so you don't get the double-margin and edge-overflow headaches that margins cause2.
The grid below has six fixed-width cards forced onto one line, so they overflow. Let them wrap onto multiple rows and space them evenly.
Notice the cards are also display: flex themselves — that is how each number is centered inside its card, using justify-content and align-items from Lesson 02. Flex containers nest freely: the grid arranges the cards, and each card arranges its own contents.
Each wrapped line is its own flex container
Once items wrap, something changes that catches people out: each flex line behaves like a separate flex container. Space distribution happens across each line independently, with no reference to the line above or below3. There are no Flexbox features that tell items in one row to line up with items in the row above1.
That single fact explains the most-reported wrapping surprise. Leave a row of growable items — say flex: 1 1 160px — and the last line will usually hold fewer items than the ones above. Because that line is its own container with its own free space to divide, its items stretch wider than their neighbors upstairs. If there is only one item on the final line, it stretches to fill the entire line1. Nothing is broken; you asked for one-dimensional distribution and got it per line.
This is also the honest boundary of the tool. Flexbox controls one axis at a time; CSS Grid controls rows and columns together, and a grid item stays in its cell rather than stretching when the last row is short1. If you catch yourself adding percentage widths to force items into columns, or inserting empty items to take up space, that is the signal to switch that component to Grid1. "Wants space distributed line by line" is the Flexbox case; "wants a true two-dimensional grid" is not.
align-content: the property that only exists once you wrap
align-items positions items within their line on the cross axis. When there are multiple lines, a different question appears: how should the set of lines be distributed in the leftover cross-axis space? That is align-content, sometimes described as packing flex lines4.
Two conditions gate it, and missing either is why it so often appears to do nothing. The container must actually wrap, and the cross-axis dimension must be larger than needed to display the lines — otherwise there is no space to distribute4. It takes the familiar vocabulary (flex-start, center, space-between, space-around, space-evenly, stretch), and its initial value behaves as stretch4.
Worth holding next to gap, because the two are easy to conflate: row-gap sets a fixed distance between lines, while align-content distributes whatever cross-axis space is left over. They compose — and both, along with margins and padding, contribute to the visible distance between items1.
Worked example (follow along)
A responsive tag list that wraps and stays evenly spaced at any width:
Reading it with the whole course: display: flex puts the tags on the main axis (Lesson 01). flex-wrap: wrap lets them break onto new lines when the row fills up, instead of overflowing. gap: 8px puts even space between every tag, horizontally and vertically, without adding a margin to the last one in a row. Resize the window and the tags reflow on their own — no media query needed for the wrapping itself.
Your turn (faded example)
You want a photo grid where each photo is 150px wide, the grid wraps, and there's 16px of space between photos. Fill in the three declarations on the container:
Answer: display: flex;, flex-wrap: wrap;, and gap: 16px;. The three lines map exactly to the three ideas: become a flex line, allow that line to break, and space the pieces. That combination is the backbone of nearly every responsive grid you'll build with Flexbox.
Summary + what's next
flex-wrap: wrap lets a flex line break onto multiple rows instead of overflowing, and gap spaces items cleanly without edge margins. Put together with the earlier lessons — display: flex, the two axes, flex-direction, and flex-grow — you now have the full toolkit for centering, nav bars, space distribution, and wrapping card rows. You are no longer guessing which property to reach for; you are reading the axes. That is the difference between fighting your layouts and directing them.
Footnotes
-
MDN: Mastering wrapping of flex items — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Wrapping_items ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
CSS-Tricks: A Complete Guide to Flexbox — https://css-tricks.com/snippets/css/a-guide-to-flexbox/ ↩
-
MDN: Basic concepts of flexbox — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Basic_concepts ↩
-
MDN: Aligning items in a flex container — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Aligning_items ↩ ↩2 ↩3
Exercises
Create a real index.html and style.css in your own editor. Build a top nav and a card row using only Flexbox, then open the file in your browser and verify it with devtools:
Level 2 (capstone — build a real page)- A nav bar: a logo on the left, a search input that grows to fill the middle (
flex-grow), and a "Sign in" button on the right, all vertically centered. - Below it, a row of six cards that wraps onto multiple rows with an even
gapas you resize the window. - Open devtools, select the nav and the card grid, and read their computed flex properties.
My note
Jot down thoughts, sticking points, things you didn't get. Written to this course's appendix only — the lesson file is never touched.