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
| Property | Values | Effect |
|---|---|---|
flex-direction | row · row-reverse · column · column-reverse | Sets the main axis direction |
flex-wrap | nowrap (default) · wrap · wrap-reverse | Whether 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.
| Value | Behavior |
|---|---|
flex-start | Pack items to the start (default) |
flex-end | Pack items to the end |
center | Center items |
space-between | Equal space between items, none at edges |
space-around | Equal space around each item (half-space at edges) |
space-evenly | Equal 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
| Property | Applies to | What it controls |
|---|---|---|
align-items | Container | Default cross-axis alignment for all items |
align-self | Individual item | Override for one item |
align-content | Container (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>;
}
| Component | Default | Meaning |
|---|---|---|
flex-grow | 0 | How much the item grows relative to siblings when there is extra space |
flex-shrink | 1 | How much the item shrinks relative to siblings when space is tight |
flex-basis | auto | The item's initial size before growing/shrinking (like width for row) |
Common patterns
| Shorthand | Expansion | Use case |
|---|---|---|
flex: 1 | 1 1 0% | Item fills available space equally |
flex: auto | 1 1 auto | Item grows from its content size |
flex: none | 0 0 auto | Item is inflexible — stays at content size |
flex: 0 1 200px | — | Item 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).
| Scenario | Use |
|---|---|
| Navbar items in a row | Flexbox |
| Card content stacked vertically | Flexbox |
| Page-level layout (header + sidebar + main + footer) | Grid |
| Magazine-style multi-column + multi-row layout | Grid |
| Complex dashboard with named regions | Grid |
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:
- What happens to the main axis and cross axis when you change
flex-directionfromrowtocolumn? - Why does
flex: 1make items share space equally, even if their content sizes differ? - When would
align-contentdo something different fromalign-items?
Navigation: ← 1.8 Overview · 1.8.b — Common Layout Patterns →