flex-wrap: one line, or as many as needed
By default a flex container keeps all its items on one line (flex-wrap: nowrap) and shrinks them to fit. flex-wrap: wrap lets them keep their size and move onto the next line instead:
Each item asks for 100px, five of them in a 340px box. Five items and four 8px gaps need 532px, so without wrapping each item is squeezed to about 62px, because flex items shrink by default. With wrap they stay 100px: three fit on the first line and the other two move to a second line.
flex-wrap values
| Value | What happens |
|---|---|
nowrap (default) | One line. Items shrink, and overflow the container once they cannot shrink further |
wrap | Items that do not fit start a new line below |
wrap-reverse | Same, but new lines stack upward: the first line is at the bottom |
Watch items wrap
Drag the slider to change the container's width. The readout counts the lines and says how many items are on each:
At 400px, four 90px items and three 8px gaps (384px) fit on a line, so you get 4 + 2. Drag toward 620px and all six fit on one line; drag toward 120px and each item gets a line of its own.
flex-direction: row or column
flex-direction sets the direction items flow in, which is the main axis:
| Value | Items run | First item |
|---|---|---|
row (default) | side by side, in the writing direction | at the start of the line |
row-reverse | side by side, reversed | at the end of the line |
column | stacked, top to bottom | at the top |
column-reverse | stacked, bottom to top | at the bottom |
In the two row boxes the items stretch to the full height of the box, because align-items: stretch works across the row. In the column boxes they stretch to the full width instead, for the same reason. The axes turned, and every alignment property turned with them (the justify-content page shows that in detail).
flex-flow: both in one line
flex-flow is the shorthand for flex-direction then flex-wrap:
.cards { flex-flow: row wrap; } /* flex-direction: row; flex-wrap: wrap; */
.stack { flex-flow: column nowrap; } /* flex-direction: column; flex-wrap: nowrap; */
Responsive cards with wrap and no media query
Give each item a starting size with flex: 1 1 180px and let the row wrap. Each item grows to fill its line, and when a line cannot fit another 180px item, the next one wraps:
In a preview about 800px wide, three cards fit on the first line (about 253px each) and the last two share the second line, where each grows to about 386px. That is how flexbox works: every line shares out its own space, so cards on a short last line end up wider than the ones above. If you want the last card to stay the same width as the others, use grid with repeat(auto-fill, minmax(180px, 1fr)) instead (see the grid page).
align-content: spacing the lines
When a container wraps and is taller than its lines, align-content decides where the lines go. It takes the same values as justify-content, plus stretch:
In the first box both lines sit at the top. In the second the first line is at the top and the second at the bottom, with all the spare height between them.
Reversed order and accessibility
row-reverse, column-reverse and wrap-reverse only change where items are drawn. Screen readers and the Tab key still follow the HTML order, so a keyboard user moves through the items in the opposite direction to what they see. Reverse for visual effect only; when the order carries meaning, change it in the HTML.
Common mistakes
- Items that shrink instead of wrapping. Items with
flex: 1start from aflex-basisof 0 and squeeze into one line. Give them a real basis, such asflex: 1 1 200px. - Putting
flex-wrapon the items. It belongs on the flex container. - Using
align-itemsto space wrapped lines. That aligns items within each line; the lines themselves move withalign-content. - A lonely last item stretched across the whole row. That is
flex-growon a line with one item. Use grid if every card must be the same width. - Expecting
flex-direction: columnto fill a height. A column container is only as tall as its content unless you give it aheight, sojustify-contenthas no room to work.
Frequently Asked Questions
What does flex-wrap: wrap do?
It lets flex items move onto a new line when they do not fit in one row. With the default nowrap, the items stay on one line and shrink, or overflow the container if they cannot shrink any further.
Why is flex-wrap not working?
Wrapping only happens when the items' starting sizes add up to more than the container. Items with flex: 1 start from a flex-basis of 0, so they never wrap; give them a real starting size (flex: 1 1 200px or width: 200px). Also check that flex-wrap is on the flex container, not the items.
What is the difference between flex-direction row and column?
row (the default) places items side by side in the writing direction, and column stacks them top to bottom. The main axis turns with it, so in a column justify-content works vertically and align-items horizontally.
What is flex-flow?
A shorthand for flex-direction and flex-wrap in one declaration: flex-flow: row wrap; is the same as flex-direction: row; flex-wrap: wrap;.
What is the difference between align-items and align-content?
align-items places items inside their line. align-content places the lines themselves inside the container, so it only matters when the container has flex-wrap: wrap and is taller than its lines.