Skip to content
Laviyx Learn

Try

CSS course menu

CSS Flexbox: A Complete Beginner's Guide with Examples

Learn CSS Flexbox with live examples: flex containers and items, flex-direction, main and cross axes, justify-content, align-items, flex-wrap, gap, align-content, and common layouts such as navbars, card rows and sticky footers.

Intermediate7 min readUpdated
On this page

Flexbox (the flexible box layout) arranges items in one direction, a row or a column, and controls how they are spaced, aligned and sized. It is the go-to tool for navigation bars, toolbars, card rows, form rows and centering.

A flex container#

Setting display: flex on an element makes it a flex container and its direct children flex items:

CSS
.row { display: flex; gap: 8px; padding: 8px; background: #eef3ff; }
.row div { padding: 12px 16px; background: #2f5fe0; color: white; border-radius: 6px; }
HTML
<div class="row">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
Result

The divs, normally stacked as blocks, now sit in a row, as wide as their content, with gap between them.

Two axes#

Flexbox works along two axes:

  • The main axis is the direction items are placed in, set by flex-direction.
  • The cross axis runs perpendicular to it.
flex-directionMain axisCross axis
row (default)left to righttop to bottom
columntop to bottomleft to right
row-reverse, column-reversereversed

justify-content aligns along the main axis. align-items aligns along the cross axis. Keeping these two straight is most of Flexbox.

justify-content: the main axis#

CSS
.row { display: flex; padding: 6px; margin-bottom: 8px; background: #eef3ff; font: 12px monospace; }
.row span { padding: 8px 12px; background: #2f5fe0; color: white; border-radius: 4px; }
HTML
<div class="row" style="justify-content: flex-start"><span>flex-start</span><span>B</span><span>C</span></div>
<div class="row" style="justify-content: center"><span>center</span><span>B</span><span>C</span></div>
<div class="row" style="justify-content: flex-end"><span>flex-end</span><span>B</span><span>C</span></div>
<div class="row" style="justify-content: space-between"><span>space-between</span><span>B</span><span>C</span></div>
<div class="row" style="justify-content: space-around"><span>space-around</span><span>B</span><span>C</span></div>
<div class="row" style="justify-content: space-evenly"><span>space-evenly</span><span>B</span><span>C</span></div>
Result

align-items: the cross axis#

CSS
.row { display: flex; gap: 6px; height: 80px; padding: 6px; margin-bottom: 8px; background: #fff3c4; font: 12px monospace; }
.row span { padding: 6px 10px; background: #e8590c; color: white; border-radius: 4px; }
.row span:nth-child(2) { padding: 18px 10px; }
HTML
<div class="row" style="align-items: stretch"><span>stretch (default)</span><span>tall</span></div>
<div class="row" style="align-items: flex-start"><span>flex-start</span><span>tall</span></div>
<div class="row" style="align-items: center"><span>center</span><span>tall</span></div>
<div class="row" style="align-items: flex-end"><span>flex-end</span><span>tall</span></div>
Result

By default (stretch), items stretch to the full height of the row, which is why flex columns in a row are automatically equal height.

Columns#

With flex-direction: column, the axes swap: justify-content now works vertically and align-items horizontally:

CSS
.col {
  display: flex;
  flex-direction: column;
  align-items: center;      /* horizontal, because the cross axis is now horizontal */
  gap: 6px;
  padding: 10px;
  background: #e6f5f3;
}
.col span { padding: 8px 14px; background: #0f8a7e; color: white; border-radius: 6px; }
HTML
<div class="col"><span>Sign in</span><span>Create an account</span><span>Help</span></div>
Result

Wrapping#

By default, flex items all stay on one line and shrink to fit. flex-wrap: wrap lets them move onto new lines:

CSS
.tags { display: flex; flex-wrap: wrap; gap: 6px; max-width: 320px; }
.tags span { padding: 4px 10px; border: 1px solid #2f5fe0; border-radius: 999px; color: #2f5fe0; }
HTML
<div class="tags">
  <span>html</span><span>css</span><span>javascript</span><span>flexbox</span>
  <span>grid</span><span>responsive</span><span>accessibility</span><span>performance</span>
</div>
Result

When lines wrap, align-content controls the spacing between the lines (it has no effect on a single line).

Common patterns#

A navigation bar#

CSS
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: #1d3b4f;
  color: white;
  font-family: system-ui, sans-serif;
}
.navbar nav { display: flex; gap: 16px; }
.navbar a { color: white; text-decoration: none; }
HTML
<header class="navbar">
  <strong>Laviyx</strong>
  <nav><a href="#">Courses</a><a href="#">Practice</a><a href="#">About</a></nav>
</header>
Result

Pushing one item to the end#

An auto margin absorbs all the free space, pushing an item (and everything after it) away:

CSS
.bar { display: flex; gap: 8px; padding: 8px; background: #f1f3f5; }
.bar button { padding: 6px 12px; }
.bar .end { margin-left: auto; }
HTML
<div class="bar">
  <button>Bold</button><button>Italic</button>
  <button class="end">Save</button>
</div>
Result
CSS
body { min-height: 100dvh; display: flex; flex-direction: column; }
main { flex: 1; }   /* main grows to fill the space, pushing the footer down */

flex: 1 is explained in Flex Items: grow, shrink and basis.

Practice#

Practice exercise

Build a card row: three cards side by side with 16px gaps that wrap onto new lines on narrow screens, where each card has equal height and its "Read more" link sits at the bottom of the card.

Show solution
CSS
.cards { display: flex; flex-wrap: wrap; gap: 16px; }
.card {
  flex: 1 1 180px;            /* grow, shrink, start at 180px: see the next lesson */
  display: flex;
  flex-direction: column;
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 10px;
}
.card a { margin-top: auto; }
HTML
<div class="cards">
  <article class="card"><h3>HTML</h3><p>Structure.</p><a href="#">Read more</a></article>
  <article class="card"><h3>CSS</h3><p>Presentation, layout, colours, fonts and animation, which takes a few more words.</p><a href="#">Read more</a></article>
  <article class="card"><h3>JavaScript</h3><p>Behaviour.</p><a href="#">Read more</a></article>
</div>
Result

The row stretches all cards to the same height; inside each card, a column flexbox with margin-top: auto on the link pushes it to the bottom.

Key takeaway#

Finished this lesson?