CSS Flexbox handles one-dimensional layouts — rows or columns. Most developers know the basics, but the advanced flex properties enable precise alignment, sizing, and ordering that solves complex real-world layout problems. Firefox has excellent Flex inspection in DevTools.

The Flex Model

Flex containers establish a flex formatting context. Children become flex items.

.container { display: flex; /* or inline-flex */ flex-direction: row; /* row (default), row-reverse, column, column-reverse */ flex-wrap: nowrap; /* nowrap (default), wrap, wrap-reverse */ /* Shorthand: */ flex-flow: row wrap; } 

Alignment

Two axes: main axis (flex-direction) and cross axis (perpendicular).

.container { /* Main axis alignment */ justify-content: flex-start; /* default */ justify-content: flex-end; justify-content: center; justify-content: space-between; /* gaps between items */ justify-content: space-around; /* gaps around items */ justify-content: space-evenly; /* equal gaps everywhere */ /* Cross axis alignment */ align-items: stretch; /* default: items stretch to fill cross size */ align-items: flex-start; align-items: flex-end; align-items: center; align-items: baseline; /* align text baselines */ /* Multi-line cross axis alignment (when flex-wrap: wrap) */ align-content: flex-start; align-content: space-between; align-content: stretch; /* Shorthand for both axes */ place-items: center; /* align-items justify-items */ place-content: space-between center; /* align-content justify-content */ } 

Flex Item Properties

.item { /* Growth factor: how much extra space item gets */ flex-grow: 0; /* default: don't grow */ flex-grow: 1; /* gets 1 share of extra space */ flex-grow: 2; /* gets 2 shares (twice as much as flex-grow: 1) */ /* Shrink factor: how much item shrinks when container is too small */ flex-shrink: 1; /* default: shrink equally */ flex-shrink: 0; /* never shrink */ /* Base size before distribution */ flex-basis: auto; /* use item's natural size */ flex-basis: 200px; /* start at 200px, then grow/shrink */ flex-basis: 0; /* ignore content size, distribute purely by flex-grow */ /* Shorthand: flex-grow flex-shrink flex-basis */ flex: 0 0 200px; /* Fixed 200px, no grow/shrink */ flex: 1; /* Same as flex: 1 1 0 — equal distribution */ flex: auto; /* flex: 1 1 auto — grow/shrink proportionally from natural size */ flex: none; /* flex: 0 0 auto — don't flex at all */ } 

The flex: 1 Shorthand

/* These are equivalent: */ .item { flex: 1; } .item { flex-grow: 1; flex-shrink: 1; flex-basis: 0; } /* vs. */ .item { flex: 1 1 auto; } /* flex-basis: auto means "start from content size" */ /* flex-basis: 0 means "ignore content, distribute proportionally" */ 

The difference matters for unequal content sizes:

  • flex: 1 (basis 0): all items get equal space regardless of content
  • flex: auto: items start at their natural size, then extra space is distributed

Per-Item Alignment Override

.container { align-items: center; } .item-special { align-self: flex-start; /* Overrides container's align-items */ } .item-fill { align-self: stretch; } 

Order

Change visual order without changing DOM order (affects tab order too, so use carefully):

.container { display: flex; } .first { order: 1; } .second { order: 2; } .third { order: -1; } /* Negative values come first */ 

Tab order follows DOM order, not visual order — using order while adding interactive content can confuse keyboard users.

Practical Patterns

Sticky Footer

body { display: flex; flex-direction: column; min-height: 100vh; } main { flex: 1; /* Grows to fill space, pushing footer down */ } footer { /* Natural size — no flex needed */ } 

Centering (Classic Flexbox Use Case)

.center-content { display: flex; align-items: center; justify-content: center; min-height: 100vh; } /* Alternative with auto margins */ .container { display: flex; } .centered-item { margin: auto; } /* Auto margins in flex: absorb all available space */ 

Navigation Bar

.navbar { display: flex; align-items: center; padding: 0 24px; gap: 16px; } .navbar .logo { margin-right: auto; } /* Pushes everything else to the right */ .navbar .menu { display: flex; gap: 8px; } .navbar .actions { display: flex; gap: 8px; } 

Card Grid with Equal Heights

.card-row { display: flex; gap: 16px; } .card { flex: 1; display: flex; flex-direction: column; } .card-content { flex: 1; } /* Pushes footer to bottom of each card */ .card-footer { /* Natural height */ } 

Firefox DevTools: Flex Inspector

Firefox's Layout panel has excellent Flex visualization:

  1. Open DevTools → Layout tab
  2. Under "Flex" section, click the flex icon on any flex container
  3. The overlay shows:
    • Item boundaries
    • Flex lines
    • Available free space
    • Item grow/shrink behavior

The overlay is interactive — hover over items to see their computed flex-grow, flex-shrink, flex-basis, and final size.

Auto Margins in Flex

Flexbox auto margins absorb free space:

.nav { display: flex; align-items: center; } .nav .logo { /* natural size */ } .nav .spacer { flex: 1; } /* Takes all free space */ .nav .login { /* natural size */ } /* Alternative: auto margin on logo pushes everything else right */ .nav .logo { margin-right: auto; } 

Both patterns achieve the same result: logo on left, login on right.