By default, a Flexbox container stubbornly refuses to let its items wrap onto a new line: they all squeeze onto a single line, even if that means overflowing the container or shrinking down to unreadable sizes. flex-wrap is the property that allows, or forbids, that switch.
It comes up whenever a layout needs to adapt to varying screen widths: a list of tags that should spread across several lines, a grid of product thumbnails, or a navigation bar that needs to reorganize on mobile without a dedicated media query.
Definition
flex-wrap is the property that decides whether the items inside a flex container can spread across several lines (or columns, depending on the direction set by flex-direction) once one line runs out of room.
.container {
display: flex;
flex-wrap: wrap;
}Without that line, every item would stay on a single line indefinitely, no matter how many there are.
The three values
| Value | Effect |
|---|---|
nowrap | Every item stays on one line, shrinking as needed (default behavior) |
wrap | Items drop onto the next line once space runs out |
wrap-reverse | Like wrap, but the lines stack in reverse order |
nowrap, the default value, explains why so many flex layouts overflow horizontally on mobile with no error ever showing up in the code: the browser is simply obeying the implicit instruction to keep everything on one line.
A concrete example
A list of skill badges shows off exactly what wrap does: the number of badges is never known ahead of time, and their combined width almost always exceeds the container's width on a narrow screen.
.badge-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}With flex-wrap: wrap, any badge that no longer fits on the current line automatically drops onto the next one, with no width calculation required.
Why almost every responsive flex layout needs it
Once a flex container shows a variable number of items, like product cards or search filters, its total width sooner or later exceeds the screen's. Without flex-wrap: wrap, those items would squeeze horizontally until they became unreadable, instead of cleanly reorganizing across several lines.
That is what makes flex-wrap so useful alongside a Media query: a single declaration is often enough to get basic responsive behavior, where a fixed grid would require recalculating a column count at every breakpoint.
The link with align-content
Once flex-wrap creates several lines, a new question comes up: how do those lines themselves spread across the container's height? That is the job of align-content, a property that stays completely without effect as long as flex-wrap is set to nowrap, since there is then only a single line to position.
align-content to a container that lacks flex-wrap: wrap, and finding that nothing happens. align-content only acts on multiple lines; without flex-wrap, every item stays on one line, and there is nothing left to distribute.Frequently asked questions
flex-wrap also change how gap behaves?gap keeps working normally with flex-wrap: wrap, but its effect becomes visible in both dimensions at once: it spaces items apart on a single line, and it also spaces the lines themselves apart once there is more than one, with no extra property required.
flex-wrap: wrap and a media query?flex-wrap reacts to the space actually available inside the container, item by item, with no fixed breakpoint. A media query reacts to the width of the whole screen, at precise thresholds set ahead of time. The two combine very well: flex-wrap handles the fine-grained adaptation, the media query handles bigger structural changes.
That is almost always because an item has a minimum width (min-width) that exceeds the space left on the current line, even if that space looks sufficient to the eye. flex-wrap strictly respects those size constraints before deciding whether an item still fits on the line.