ESC

Type to search the knowledge base.

Flexbox Fundamentals

Flex container vs items, main vs cross axis, grow/shrink/basis, alignment, wrapping, and the bugs that show up in real layouts.

beginner4 min read
  • css
  • flexbox
  • layout

Flexbox is a one-dimensional layout model: you distribute space along a row or a column, then optionally wrap. Grid is two-dimensional. Most nav bars, toolbars, card footers, and form rows are flex problems — not grid problems.

Docs: MDN Flexbox, web.dev Learn CSS — Flexbox.

Container vs items

.toolbar {
  display: flex;          /* children become flex items */
  flex-direction: row;    /* main axis → horizontal */
  gap: 0.75rem;           /* preferred over margin hacks */
}
  • Flex container — the element with display: flex or inline-flex
  • Flex items — its in-flow children (not absolutely positioned descendants)

Only direct children are flex items. Nested structures need their own flex/grid contexts.

Main axis and cross axis

flex-direction Main axis Cross axis
row (default) left → right top → bottom
row-reverse right → left top → bottom
column top → bottom left → right
column-reverse bottom → top left → right

Every alignment property is relative to these axes. Memorize “main vs cross,” not only “horizontal vs vertical.”

.stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

Distributing free space on the main axis

.nav {
  display: flex;
  justify-content: space-between; /* main-axis packing */
  align-items: center;            /* cross-axis alignment of items */
}

justify-content common values: flex-start | flex-end | center | space-between | space-around | space-evenly.

align-items (cross axis, one line): stretch (default) | flex-start | flex-end | center | baseline.

Per-item override: align-self.

<header class="nav">
  <a class="logo" href="/">Frontend Beauty</a>
  <nav class="links">…</nav>
  <button type="button">Sign in</button>
</header>
.nav {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.links {
  display: flex;
  gap: 1rem;
  margin-inline-start: auto; /* push remaining items to the end */
}

margin: auto on a flex item absorbs free space — often cleaner than nested space-between hacks.

flex-grow, flex-shrink, flex-basis

Shorthand: flex: <grow> <shrink> <basis>

Property Role
flex-basis Ideal size before free space is distributed (auto ≈ content/width)
flex-grow Share of extra free space (0 = don’t grow)
flex-shrink Share of deficit when overflowing (0 = don’t shrink)
.sidebar {
  flex: 0 0 240px; /* fixed-ish rail */
}
.main {
  flex: 1 1 auto;  /* take the rest, can shrink */
  min-width: 0;    /* critical: allow shrink below content min */
}

The min-width: auto footgun

By default, flex items won’t shrink smaller than their content’s minimum size. Long words / wide tables blow out the layout. Fix:

.main {
  flex: 1;
  min-width: 0; /* or min-height: 0 in a column flex */
  overflow: auto;
}

Same issue appears in nested flex/grid dashboards — if a child won’t scroll, check min-size constraints.

Useful shorthands

flex: 1;        /* 1 1 0% — equal flexible columns (basis 0) */
flex: auto;     /* 1 1 auto */
flex: none;     /* 0 0 auto — size to content, no grow/shrink */

flex: 1 vs flex: auto differs in how basis starts; for equal columns, flex: 1 + min-width: 0 is a common pattern.

Wrapping

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

With wrap, you get multiple flex lines. Then:

  • align-content distributes lines on the cross axis (not align-items)
  • align-items still aligns items within each line
.gallery {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 1rem;
}

Ordering and accessibility

order changes visual order without changing DOM order. Screen readers and tab order follow the DOM. Don’t use order to fix reading order for keyboard users — reorder the markup.

Centering (the meme, correctly)

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

For a single centered child, place-items on grid is also fine. Flex remains ideal when the bar has multiple items with different packing rules.

Flex vs Grid (when to choose)

Use flex when… Use grid when…
One axis controls the design Rows and columns matter together
Nav, toolbars, media objects Page scaffolding, card matrices
Content-driven item sizes Explicit tracks (1fr 2fr, areas)

They compose: a grid cell can be a flex container.

Interview angle

Draw main vs cross for flex-direction: column. Explain flex: 1 and why min-width: 0 fixes overflow. Contrast justify-content vs align-items vs align-content.

Live coding: build a header with logo left, links right, and a wrapping chip list — without absolute positioning.

Further reading

Related guides