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:
- Open DevTools → Layout tab
- Under "Flex" section, click the flex icon on any flex container
- 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.
Top comments (0)