Flexbox

Flexbox lays out a group of items along one axis — a row or a column — with real control over alignment and how items grow or shrink. It is the right tool for toolbars, media objects, form rows, and card contents. It is the wrong tool for a whole page grid; that is Grid's job.

The container and its axes

Two axes, not four sides

Flex container showing the main axis and cross axis with three items
Flexbox alignment is axis-based: justify-content works along the main axis, align-items across it. flex-direction: column swaps them.
/* The container declares flexbox; everything else keys off its axes */
.nav {
  display: flex;
  flex-direction: row;            /* main axis = horizontal (the default) */
  justify-content: space-between; /* distribute along the MAIN axis */
  align-items: center;            /* align across the CROSS axis */
  gap: 1rem;                      /* spacing BETWEEN items - replaces margin tricks */
}

The single most useful habit: think in axes, not in horizontal/vertical. When flex-direction: column, justify-content becomes vertical — the property did not change meaning, the axis did. This one insight resolves most flexbox confusion.

Wrapping is opt-in

/* A flex row NEVER wraps by default: items shrink or overflow instead.
   For a responsive card row without media queries: */
.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.card-row > * {
  flex: 1 1 16rem;   /* each card: at least 16rem, may stretch to share the row */
}

Flex items: growing and shrinking

The flex shorthand reads: grow, shrink, basis

/* flex: <grow> <shrink> <basis>
   basis  = the ideal size before free space is shared
   grow   = share of EXTRA space (0 = never grow)
   shrink = willingness to shrink below basis (default 1) */
.sidebar { flex: 0 0 16rem; }   /* fixed rail: never grows, never shrinks */
.content { flex: 1; }           /* takes ALL remaining space (basis 0%, grow 1) */
.card    { flex: 1 1 16rem; }   /* ideal 16rem, grows and shrinks with siblings */

Grow factors distribute proportionally, not absolutely. Two items with flex: 1 split the free space evenly; flex: 2 takes twice as much of the extra space, not twice the total width. Keeping that distinction straight prevents most "why is my column wider" surprises.

The auto-margin trick

/* justify-content spreads ALL items; a single auto margin absorbs
   all free space on ONE side - the "push the last item right" idiom */
.nav { display: flex; gap: 1rem; }
.nav .login { margin-inline-start: auto; }

The patterns you will use daily

The media object

/* Icon + text, icon stays put, text wraps within its own column */
.media { display: flex; gap: 0.75rem; align-items: flex-start; }
.media .icon { flex: 0 0 auto; }     /* never grows, never shrinks */
.media .body { min-width: 0; }       /* allows the text to shrink and wrap */
.media .title { overflow-wrap: anywhere; } /* long words cannot push the layout out */
/* The entire "how do I center a div" answer */
.center {
  display: flex;
  justify-content: center;  /* main axis */
  align-items: center;      /* cross axis */
  min-height: 12rem;
}

/* Sticky footer: page fills the viewport, footer pinned to the bottom */
body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;   /* dynamic viewport height: correct on mobile */
}
main { flex: 1; }        /* the content area absorbs the free space */

Equal-height cards and the gap habit

/* stretch (the default align-items) gives equal heights for free;
   the CARD is a flex column so its footer can be pushed to the bottom */
.card-row { display: flex; gap: 1rem; }
.card {
  display: flex;
  flex-direction: column;
}
.card .actions { margin-top: auto; }  /* aligned across cards of different text length */

Flexbox or Grid?

A rule of thumb, with exceptions

Flexbox for content-driven one-dimensional groups: the number of items is unknown, items size themselves. Grid for layout-driven two-dimensional structures: rows and columns are declared regardless of content. Components routinely mix them — a grid page shell containing flex toolbars containing flex media objects.

Practice: flex workout

The task

Open demo/layout/15_flexbox_patterns.html from the Lab Examples page and rebuild each pattern from memory.

The checklist

  • Build a toolbar: brand left, links center-right, login pushed fully right with one auto margin.
  • Build a card row that goes 3 → 2 → 1 columns by resizing, with no media query.
  • Explain the difference between flex: 1 and flex: 0 0 auto on a sibling pair.
  • Center a box in a viewport-height section using dvh, then shrink the window to verify it never overflows.