Encodera

Thanks for reading!

Donate to the site — we work hard for you.

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.

Thanks for reading!

Donate to the site — we work hard for you.