References

Beginner-friendly references for web development, with live, editable examples.

The CSS flex-direction property

Property CSS All modern browsers Updated
Quick answer

The CSS flex-direction property decides whether flex items run in a row (the default, left to right) or a column (top to bottom). The row-reverse and column-reverse values flip the visual order. It also sets which axis justify-content and align-items act on.

Overview

flex-direction sets the main axis of a flex container, which is a fancy way of saying it decides whether the items sit side by side or stacked. The default, row, lays them out left to right; column stacks them top to bottom.

Because it defines the main axis, it quietly changes what the alignment properties do. In a row, justify-content works horizontally and align-items works vertically. Switch to column and the two swap: justify-content now runs top to bottom. That trips people up, so it is worth keeping in mind whenever a layout suddenly aligns the "wrong" way.

The row-reverse and column-reverse values reverse the visual order of the items. They are genuinely useful (for example, putting the most important button last in the markup but first on screen), but they come with an accessibility catch worth reading below.

Syntax

selector {
  display: flex;
  flex-direction: value;
}

/* stack on a card */
.card {
  display: flex;
  flex-direction: column;
}

Values

The flex-direction property accepts the values below. Every property also accepts the CSS-wide keywords inherit, initial, revert and unset.

Value Description
row Items flow left to right along a horizontal main axis. The default.
column Items stack top to bottom along a vertical main axis.
row-reverse Like row, but the visual order is reversed (right to left).
column-reverse Like column, but the visual order is reversed (bottom to top).

Example

Live example
<style>
  .card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: #f5f7fb;
    padding: 16px;
    border-radius: 10px;
    font: 14px system-ui, sans-serif;
  }
  .card div { background: #1c7ce9; color: #fff; padding: 10px; border-radius: 6px; text-align: center; }
</style>
<div class="card">
  <div>First</div>
  <div>Second</div>
  <div>Third</div>
</div>

Best practices

  • Use column for stacked card layouts and row for toolbars and nav bars, then let the alignment properties do the fine-tuning.
  • Remember the alignment axes swap with direction: in a column, justify-content controls vertical position and align-items controls horizontal.
  • Combine flex-direction with a media query (row on desktop, column on mobile) for layouts that reflow without extra markup.
  • Avoid the reverse values purely for visual reordering; they desync the tab order. Reorder the HTML instead when the change is meaningful.

Accessibility

The reverse values, and the related order property, change only the visual order of flex items. They do not change the DOM order, which is what keyboard focus and screen readers follow. So a keyboard user can end up tabbing through your buttons right-to-left while seeing them left-to-right, which is disorienting.

The WCAG guidance on meaningful sequence is clear here: if the order matters, it should be correct in the markup. Use row-reverse for genuinely cosmetic flips, and when the reordering is meaningful, change the HTML so the visual and focus order stay in step.

Frequently asked questions

How do I stack flex items vertically?
Set flex-direction: column on the container. The items stack top to bottom instead of sitting in a row.
Why did justify-content stop working when I used flex-direction: column?
Because the axes swap. In a column, justify-content controls the vertical position and align-items controls the horizontal, the opposite of a row.
What does flex-direction: row-reverse do?
It reverses the visual order of the items along the row, so they read right to left. The underlying HTML order, and therefore the tab order, stays the same.
Is row-reverse bad for accessibility?
It can be. It changes what users see but not the order keyboard and screen-reader users move through. Only use it for cosmetic flips; reorder the markup when the sequence actually matters.