Flexbox Advanced Patterns
Patterns That Solve Real Layout Problems
Alright, you know flex-grow and justify-content. Now let's actually use them. This lesson covers the flexbox patterns that appear in every production application -- the ones you'll reach for daily. Each one solves a specific layout problem that was genuinely painful before flexbox existed.
Think of advanced flexbox as recipes, not ingredients. You already know the ingredients (flex-grow, flex-wrap, align-items). Now you combine them into reliable recipes: the holy grail layout, the sticky footer, the card grid. Each recipe is a pattern — memorize the pattern, not just the properties.
Pattern 1: The Holy Grail Layout
Header, footer, three-column body with flexible center:
.page {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
.header, .footer {
flex-shrink: 0; /* Don't shrink these */
}
.body {
display: flex;
flex: 1; /* Takes all remaining vertical space */
}
.sidebar-left {
flex: 0 0 250px; /* Fixed 250px, no grow/shrink */
}
.content {
flex: 1; /* Fills remaining horizontal space */
min-width: 0; /* Prevents overflow (see gotchas) */
}
.sidebar-right {
flex: 0 0 200px;
}
Pattern 2: Sticky Footer
Footer stays at the bottom even when content is short:
.page {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
.main {
flex: 1; /* Pushes footer to bottom when content is short */
}
.footer {
flex-shrink: 0;
}
The trick: min-height: 100dvh on the container and flex: 1 on the main content. When content is short, flex: 1 stretches the main area to push the footer down. When content is long, the page scrolls naturally.
Pattern 3: Equal-Height Cards
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 300px; /* Grow, shrink, min 300px */
display: flex;
flex-direction: column;
}
.card-body {
flex: 1; /* Stretches to fill card — keeps action at bottom */
}
.card-actions {
margin-top: auto; /* Pushed to bottom regardless of content height */
}
Now here's a trick worth memorizing: in flexbox, auto margins absorb all available space in that direction. Setting margin-top: auto on the last element pushes it to the bottom -- perfect for card footers and button groups.
Pattern 4: Centering (Truly Centered)
/* Horizontal and vertical center */
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100dvh;
}
/* Or with place-content shorthand */
.container {
display: flex;
place-content: center;
/* Note: place-content with one value sets both align-content
and justify-content. For single items, this works like
justify-content + align-items. */
}
/* Or with margin auto */
.container { display: flex; }
.centered-item { margin: auto; }
Pattern 5: Navigation with Spacer
.nav {
display: flex;
align-items: center;
gap: 1rem;
}
.nav-spacer {
flex: 1; /* Absorbs all space, pushing items to edges */
}
/* OR: Use auto margin without a spacer element */
.nav .right-items {
margin-left: auto; /* Pushes right items to the end */
}
Pattern 6: Responsive Wrapping Cards
.grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 calc(33.333% - 1rem); /* Three columns with gap */
min-width: 280px; /* Wrap to fewer columns on smaller screens */
}
The last-row alignment problem: when flex-wrap produces a last row with fewer items, those items stretch to fill the row if they have flex-grow. A 3-column grid with 5 items shows 3 items in row 1 and 2 stretched items in row 2. If you want consistent column sizing, use CSS Grid instead — it's designed for two-dimensional alignment. Flexbox is one-dimensional and doesn't align across rows.
Flexbox Gotchas
These will bite you if you're not ready for them.
Gotcha 1: min-width: auto Causes Overflow
/* Problem: Long text overflows the flex container */
.sidebar { flex: 0 0 200px; }
.content { flex: 1; }
.content .title { white-space: nowrap; } /* Very long title */
/* .content overflows its flex allocation */
/* Fix: Override the default min-width: auto */
.content {
flex: 1;
min-width: 0; /* Allow shrinking below content size */
}
This one is so common. By default, flex items have min-width: auto, which means they won't shrink below their content's minimum size. This causes overflows with long text, large images, or white-space: nowrap.
Gotcha 2: Images in Flex Containers
/* Problem: Image doesn't shrink or distorts */
.container { display: flex; }
/* Fix: Constrain the image */
.container img {
min-width: 0; /* Allow shrinking */
object-fit: cover; /* Maintain aspect ratio */
width: 100%;
}
Gotcha 3: Margin Collapse Doesn't Happen
/* In normal flow: vertical margins collapse */
/* In flexbox: margins NEVER collapse */
.flex-col {
display: flex;
flex-direction: column;
}
.flex-col > * {
margin: 20px 0; /* Full 40px between items, not 20px */
}
/* Use gap instead of margin for predictable spacing */
| What developers do | What they should do |
|---|---|
| Using flexbox for a two-dimensional grid layout Flexbox is one-dimensional — it can't align items across wrapped rows | Use CSS Grid for anything that needs alignment in both rows AND columns |
| Forgetting min-width: 0 on flex items with long content Default min-width: auto prevents flex items from shrinking below content size | Always add min-width: 0 when flex items contain text that might overflow |
| Using margin for spacing between flex items Margins don't collapse in flexbox and gap handles edge cases (first/last item) automatically | Use the gap property for consistent spacing |
| Using order for meaningful content reordering Keyboard and assistive technology users still experience DOM order. Use order only for visual polish. | order changes visual order but NOT tab order or screen reader order |
- 1Use margin-top: auto in flex column layouts to push elements to the bottom
- 2Always add min-width: 0 on flex items that contain potentially long content
- 3Flexbox is one-dimensional — use CSS Grid when you need alignment across rows AND columns
- 4gap replaces margins for spacing between flex items — cleaner and handles edges correctly
- 5order changes visual order only, not tab order or screen reader order