Learn / Programming / HTML & CSS / Flexbox Layout

HTML & CSS · Lesson 4 of 5

Flexbox Layout

Align and distribute items in one dimension.

  • Intermediate
  • 15 min read
  • 3 objectives

Before this lessonLesson 3: CSS Basics

What you will learn

  • Use flex containers
  • Align and space items
  • Build a nav bar and cards row

Flexbox lays items out along one axis (a row or a column) and makes alignment, spacing and distributing free space easy. It replaced hacks with floats and is the right tool for nav bars, toolbars, card rows and centering.

Layout used to be painful

For years developers used hacks to place things side by side or centre them. Flexbox solved the everyday cases: it lays children out in a row or column, spaces them, aligns them and lets them share space. You switch it on with one line on the parent, and the children obey.

.row {
  display: flex;   /* children now sit in a row */
  gap: 16px;
}

The basics

Set display: flex on the container. Its direct children become flex items.

.row {
  display: flex;
  gap: 1rem;                 /* space between items */
}
<div class="row">
  <div>One</div><div>Two</div><div>Three</div>
</div>

Two axes

  • Main axis: the direction items flow, set by flex-direction (row by default, or column). Controlled by justify-content.
  • Cross axis: perpendicular to it. Controlled by align-items.
.bar {
  display: flex;
  justify-content: space-between;  /* start | center | end | space-between | space-around | space-evenly */
  align-items: center;             /* stretch | start | center | end | baseline */
}

Perfect centering

.center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

How items grow and shrink

Three properties on items control sizing: flex-grow (share of spare space), flex-shrink (willingness to get smaller) and flex-basis (starting size). The shorthand flex: 1 means "grow to fill equally".

.sidebar { flex: 0 0 240px; }   /* fixed width, never grows or shrinks */
.content { flex: 1; }            /* takes all remaining space */

Wrapping

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.cards > .card {
  flex: 1 1 260px;      /* at least 260px, share leftover space */
}

Items wrap onto new lines when they would drop below their basis, giving a responsive card row without media queries.

A typical nav bar

.nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.nav .logo { margin-right: auto; }   /* pushes everything after it to the right */

Two axes, two properties

Flexbox has a main axis (the direction items flow, a row by default) and a cross axis (the perpendicular direction). justify-content distributes items along the main axis; align-items aligns them on the cross axis. Memorise that pair and most layouts fall out.

.nav {
  display: flex;
  justify-content: space-between;  /* logo left, links right */
  align-items: center;             /* vertically centred */
  padding: 12px 24px;
}

The famous centring trick

.hero {
  display: flex;
  justify-content: center;   /* horizontal */
  align-items: center;       /* vertical */
  min-height: 100vh;
}

A card row that wraps on small screens

<div class="cards">
  <div class="card">One</div>
  <div class="card">Two</div>
  <div class="card">Three</div>
</div>
.cards {
  display: flex;
  flex-wrap: wrap;   /* move to a new line when out of space */
  gap: 16px;
}
.card {
  flex: 1 1 240px;   /* grow, shrink, start at 240px wide */
}

The flex shorthand means "grow to share extra space, shrink if needed, start at this size." With wrapping, the cards form three columns on a laptop, two on a tablet and one on a phone, with no media query.

Common flexbox questions

  • Items will not wrap: add flex-wrap: wrap.
  • Want a column instead of a row: flex-direction: column; the axes swap, so justify-content now works vertically.
  • One item pushed to the far end: give it margin-left: auto.
  • Does nothing: display: flex must be on the parent, not the items.

Key takeaways

  • Put display: flex on the parent to lay its children out in a row.
  • justify-content works along the main axis; align-items works across it.
  • gap spaces items; flex-wrap lets them flow onto new lines; flex: 1 shares space.
  • Flexbox is for one dimension (a row or a column); use Grid for two.
// Write your solution here
Up next · Lesson 5Grid and Responsive DesignTwo-dimensional layouts, media queries and mobile-first CSS.