DataLens

Flexbox

Lay out items in a row or column with display flex, align them along both axes with justify-content and align-items, space them with gap, wrap them, and let items grow with flex.

Level: Intermediate · 7 min read

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

The idea

Before flexbox, putting three things side by side, or centring something vertically, required hacks. Flexbox is a layout mode for arranging items in one direction, a row or a column, and controlling how they share space and line up. Navigation bars, toolbars, card rows, centring a dialog: flexbox handles all of them in a few lines.

Turning it on

Toko Kita's navigation is three links. By default they'd sit wherever the text flows, with no control over spacing. One line of CSS on the <nav> turns it into a flex container, and the links line up in a tidy row:

<style>
  .nav { display: flex; gap: 1rem; padding: 1rem; background: #fff4e5; }
</style>

<nav class="nav">
  <a href="/">Home</a>
  <a href="/coffee">Coffee</a>
  <a href="/equipment">Equipment</a>
</nav>

display: flex on a container makes its direct children flex items, laid out in a row. gap adds space between items (not around them), which beats margins on every item.

Two axes

Flexbox thinks in two directions:

justify-content aligns items along the main axis; align-items along the cross axis.

<style>
  .bar { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 1rem; background: #7a4b2a; color: white; }
  .bar .logo { font-size: 1.5rem; font-weight: bold; }
  .bar nav { display: flex; gap: 1rem; }
  .bar a { color: white; }
</style>

<header class="bar">
  <span class="logo">Toko Kita</span>
  <nav><a href="/coffee">Coffee</a><a href="/about">About</a><a href="/cart">Cart (2)</a></nav>
</header>
justify-contentEffect on the main axis
flex-start (default)packed at the start
centerpacked in the middle
flex-endpacked at the end
space-betweenfirst and last at the edges, equal space between
space-around / space-evenlyequal space around / between and at the edges

align-items takes stretch (the default: items fill the cross axis), flex-start, center, flex-end and baseline.

Centring anything

For years, "how do I centre something vertically?" was one of the most asked questions in web development. With flexbox, it's a famous one-liner (well, three lines): centre along the main axis, and centre along the cross axis:

<style>
  .hero { display: flex; justify-content: center; align-items: center; height: 200px; background: #fff4e5; }
</style>

<section class="hero"><p>Perfectly centred.</p></section>

Direction and wrapping

A row isn't always what you want. A row of product cards should continue on the next line when the screen is too narrow, rather than squashing every card. And a set of buttons might look better stacked on top of each other. Two properties handle that:

<style>
  .cards { display: flex; flex-wrap: wrap; gap: 1rem; }
  .card { width: 160px; padding: 1rem; border: 1px solid #ddd; }
  .stack { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 1rem; }
</style>

<div class="cards">
  <div class="card">Arabica Gayo</div><div class="card">Toraja Kalosi</div>
  <div class="card">Kintamani</div><div class="card">Flores Bajawa</div>
</div>
<div class="stack"><button>Add to cart</button><button>Save for later</button></div>

Growing and shrinking

Items can share leftover space with the flex property on the item:

<style>
  .layout { display: flex; gap: 1rem; }
  .sidebar { width: 180px; flex-shrink: 0; background: #fff4e5; padding: 1rem; }
  .content { flex: 1; background: #f5f5f5; padding: 1rem; }
  .search { display: flex; gap: 0.5rem; margin-top: 1rem; }
  .search input { flex: 1; }
</style>

<div class="layout">
  <aside class="sidebar">Filters</aside>
  <main class="content">Products take all the remaining width.</main>
</div>
<form class="search"><input type="search" aria-label="Search"><button>Search</button></form>
Key idea

display: flex on the container; gap for spacing; justify-content for the main axis, align-items for the cross axis; flex-direction and flex-wrap for flow; flex: 1 on an item to make it fill the remaining space.

Why this matters for clean code

Flexbox replaces piles of margins, floats and fixed widths with a few intent-revealing properties: "space these out", "centre this", "this part fills the rest". Layout code that states intent is easier to read and survives content changes: add a fourth nav link, and the layout just works.

Recap

Practise this module

The questions for this lesson run in your browser and check your answer straight away.