Episode 1 — Fundamentals / 1.8 — CSS Layout Mastery

1.8.a — Flexbox Deep Dive

In one sentence: Flexbox is a one-dimensional layout engine — it distributes space and aligns items along a main axis (row or column) with powerful controls for wrapping, growing, shrinking, and ordering.

Navigation: ← 1.8 Overview · 1.8.b — Common Layout Patterns →


1. Flex container vs flex items

Setting display: flex (or inline-flex) on an element creates a flex container. Its direct children become flex items.

.container {
  display: flex;   /* block-level flex container */
}

Only direct children are flex items — grandchildren follow normal flow unless their parent is also a flex container.


2. Main axis vs cross axis

Every flex container has two axes:

flex-direction: row (default)

Main axis ──────────────────────►
┌──────┐  ┌──────┐  ┌──────┐
│ Item │  │ Item │  │ Item │    Cross
│  1   │  │  2   │  │  3   │    axis
└──────┘  └──────┘  └──────┘      │
                                  ▼

flex-direction: column

Cross axis ──────────────────►
┌──────┐
│ Item 1│  Main
├──────┤  axis
│ Item 2│   │
├──────┤    ▼
│ Item 3│
└──────┘

Everything in flexbox — alignment, distribution, growing — references these two axes. Change the direction, and the meaning of "justify" and "align" swaps.


3. flex-direction, flex-wrap, flex-flow

PropertyValuesEffect
flex-directionrow · row-reverse · column · column-reverseSets the main axis direction
flex-wrapnowrap (default) · wrap · wrap-reverseWhether items wrap to new lines
flex-flow<direction> <wrap>Shorthand for both
.container {
  flex-flow: row wrap; /* items flow left-to-right, wrap when out of space */
}

4. Main-axis distribution: justify-content

Controls how free space is distributed along the main axis.

ValueBehavior
flex-startPack items to the start (default)
flex-endPack items to the end
centerCenter items
space-betweenEqual space between items, none at edges
space-aroundEqual space around each item (half-space at edges)
space-evenlyEqual space between items and at edges
space-between:    [A          B          C]
space-around:     [  A     B     C  ]
space-evenly:     [   A    B    C   ]

5. Cross-axis alignment: align-items, align-self, align-content

PropertyApplies toWhat it controls
align-itemsContainerDefault cross-axis alignment for all items
align-selfIndividual itemOverride for one item
align-contentContainer (only with wrapping)Distribution of wrapped lines

Common align-items values: stretch (default) · flex-start · flex-end · center · baseline.

.container {
  display: flex;
  align-items: center;  /* vertically center all items (when row) */
}

.special-item {
  align-self: flex-end; /* this one sits at the bottom */
}

6. The flex shorthand: grow, shrink, basis

The flex property on a flex item controls how it grows, shrinks, and what its initial size is.

.item {
  flex: <grow> <shrink> <basis>;
}
ComponentDefaultMeaning
flex-grow0How much the item grows relative to siblings when there is extra space
flex-shrink1How much the item shrinks relative to siblings when space is tight
flex-basisautoThe item's initial size before growing/shrinking (like width for row)

Common patterns

ShorthandExpansionUse case
flex: 11 1 0%Item fills available space equally
flex: auto1 1 autoItem grows from its content size
flex: none0 0 autoItem is inflexible — stays at content size
flex: 0 1 200pxItem starts at 200px, can shrink, won't grow
/* Three equal-width columns */
.col { flex: 1; }

/* Sidebar fixed, main grows */
.sidebar { flex: 0 0 250px; }
.main    { flex: 1; }

7. gap

The gap property (formerly grid-gap, now unified) adds space between items without affecting edges.

.container {
  display: flex;
  gap: 16px;        /* row-gap and column-gap */
  /* or */
  gap: 16px 24px;   /* row-gap column-gap */
}

Before gap, developers used margin on items with negative margin on the container — gap is cleaner and avoids edge-space hacks.


8. order

Each flex item has a default order: 0. Changing it reorders items visually without changing the DOM.

.item-last { order: 1; }  /* pushed to the end visually */

Accessibility warning: Screen readers follow DOM order, not visual order. Use order for minor visual tweaks, not major content reordering — it can confuse keyboard navigation.


9. Common flexbox patterns

Centering (the classic)

.center-me {
  display: flex;
  justify-content: center;
  align-items: center;
}

Spacer pattern (push one item to the far end)

.nav {
  display: flex;
  align-items: center;
}
.nav .spacer { flex: 1; } /* or use margin-left: auto on the last item */

Equal-height cards

.card-row {
  display: flex;
  gap: 16px;
}
.card {
  flex: 1;
  /* all cards stretch to equal height by default (align-items: stretch) */
}

10. When NOT to use flexbox

Flexbox is one-dimensional — it controls either a row or a column at a time. If you need to control both rows and columns simultaneously (a true 2D grid), reach for CSS Grid (1.8.c).

ScenarioUse
Navbar items in a rowFlexbox
Card content stacked verticallyFlexbox
Page-level layout (header + sidebar + main + footer)Grid
Magazine-style multi-column + multi-row layoutGrid
Complex dashboard with named regionsGrid

Rule of thumb: Flex for components, Grid for page layouts. In practice you will combine both — see 1.8.d.


Explain-It Challenge

Explain without notes:

  1. What happens to the main axis and cross axis when you change flex-direction from row to column?
  2. Why does flex: 1 make items share space equally, even if their content sizes differ?
  3. When would align-content do something different from align-items?

Navigation: ← 1.8 Overview · 1.8.b — Common Layout Patterns →