How to stack columns on mobile
Short answer
Make a flex column by default and turn it into a row on a wide screen:
<style>
.row { display: flex; flex-direction: column; gap: 12px; }
.row div { flex: 1; padding: 12px; background: lavender; }
@media (min-width: 500px) { .row { flex-direction: row; } }
</style>
<div class="row"><div>Photo</div><div>Description</div><div>Price</div></div>Without media queries
With flex-wrap the columns wrap by themselves when each one lacks the minimum width set in flex-basis:
<style>
.wrap { display: flex; flex-wrap: wrap; gap: 12px; }
.wrap div { flex: 1 1 180px; padding: 12px; background: honeydew; }
</style>
<div class="wrap"><div>Photo</div><div>Description</div></div>flex: 1 1 180px means "start at 180px, grow and shrink". When two 180px blocks do not fit, the second one moves to a new line and stretches across the full width.
Changing the order
If the image should come after the text on a phone, use flex-direction: column-reverse or order. Keep in mind that the keyboard and screen readers follow the HTML order, so do not shuffle things much.
Common mistake
width: 33% on the columns keeps them from stacking properly: even in a column they stay a third wide. In flexbox set column widths with flex, not width.
Functions used in this recipe
- flex-wrap — Whether flex items may wrap onto new lines.
- flex-direction — The direction of the main axis of a flex container: items in a row or in a column.
- @media — Applies rules only under given conditions — the window width, the system theme and others.
- flex-basis — The starting size of a flex item along the main axis, before free space is shared.