CSS Flexbox Wrapping and Alignment Patterns
Understanding how flex-wrap works with alignment properties unlocks powerful responsive layout patterns. When flex items wrap to multiple lines, you gain access to additional alignment controls that transform how you build adaptive interfaces.
Understanding Flex Wrap
By default, flex items try to fit on a single line, shrinking if necessary. The flex-wrap property changes this behavior, allowing items to flow onto multiple lines.
.container {
display: flex;
flex-wrap: nowrap; /* Default - single line */
}
.container-wrap {
display: flex;
flex-wrap: wrap; /* Items wrap to new lines */
}
.container-reverse {
display: flex;
flex-wrap: wrap-reverse; /* Wrap upward instead of down */
}Practical Wrapping Examples
/* Responsive card layout */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card {
flex: 1 1 300px; /* Grow, shrink, min 300px base */
max-width: 100%;
}
/* Tag/chip list */
.tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag {
flex: 0 0 auto; /* Don't grow or shrink */
padding: 4px 12px;
background: #f3f4f6;
border-radius: 9999px;
}Align-Content: Multi-Line Alignment
The align-content property controls how multiple flex lines are distributed along the cross axis. It only has an effect when there are multiple lines (flex-wrap: wrap) and extra space in the container.
.container {
display: flex;
flex-wrap: wrap;
height: 400px; /* Fixed height creates extra space */
/* align-content values */
align-content: flex-start; /* Lines packed at start */
align-content: flex-end; /* Lines packed at end */
align-content: center; /* Lines centered */
align-content: space-between; /* First line at start, last at end */
align-content: space-around; /* Equal space around each line */
align-content: space-evenly; /* Equal space between all lines */
align-content: stretch; /* Lines stretch to fill (default) */
}Align-Content Examples
/* Centered multi-line content */
.centered-wrap {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
min-height: 100vh;
gap: 20px;
}
/* Items spread across height */
.spread-vertical {
display: flex;
flex-wrap: wrap;
align-content: space-between;
height: 500px;
}
/* Top-aligned with natural flow */
.top-aligned {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
gap: 16px;
}Combining Alignment Properties
When using flex-wrap, you often need to coordinate multiple alignment properties:
- justify-content: Aligns items along the main axis
- align-items: Aligns items along the cross axis within each line
- align-content: Aligns the lines themselves
.gallery {
display: flex;
flex-wrap: wrap;
/* Items centered horizontally */
justify-content: center;
/* Items centered vertically within their line */
align-items: center;
/* Lines centered vertically in container */
align-content: center;
min-height: 100vh;
gap: 16px;
}
.gallery-item {
flex: 0 0 auto;
width: 200px;
height: 150px;
}Responsive Patterns with Flex Wrap
Auto-Filling Grid
.auto-grid {
display: flex;
flex-wrap: wrap;
}
.auto-grid > * {
flex: 1 1 250px; /* Min 250px, grows equally */
}
/* With max-width constraint */
.auto-grid-capped > * {
flex: 1 1 250px;
max-width: 400px;
}Equal Width Items Per Row
/* Always 3 items per row */
.three-col {
display: flex;
flex-wrap: wrap;
}
.three-col > * {
flex: 0 0 calc(33.333% - 16px);
margin: 8px;
}
/* Using gap instead */
.three-col-gap {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.three-col-gap > * {
flex: 0 0 calc((100% - 32px) / 3);
}Responsive Column Count
.responsive-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.responsive-grid > * {
/* Base: full width (1 column) */
flex: 1 1 100%;
}
@media (min-width: 600px) {
.responsive-grid > * {
/* 2 columns */
flex: 1 1 calc(50% - 10px);
}
}
@media (min-width: 900px) {
.responsive-grid > * {
/* 3 columns */
flex: 1 1 calc(33.333% - 14px);
}
}
@media (min-width: 1200px) {
.responsive-grid > * {
/* 4 columns */
flex: 1 1 calc(25% - 15px);
}
}Last Row Alignment Issues
A common challenge with flex-wrap is the last row stretching oddly when items don't fill it completely.
/* Problem: last row items stretch */
.problem-grid {
display: flex;
flex-wrap: wrap;
}
.problem-grid > * {
flex: 1 1 200px;
/* If last row has 1 item, it stretches to 100% */
}
/* Solution 1: Don't let items grow */
.solution-1 > * {
flex: 0 1 200px;
/* Items won't grow, maintains size */
}
/* Solution 2: Use max-width */
.solution-2 > * {
flex: 1 1 200px;
max-width: 300px;
}
/* Solution 3: Invisible spacer items */
.solution-3::after {
content: '';
flex: 1 1 200px;
max-width: 300px;
height: 0;
/* Takes up space but invisible */
}Flex-Flow Shorthand
Combine flex-direction and flex-wrap in one declaration:
.container {
/* flex-flow: <direction> <wrap> */
flex-flow: row wrap;
flex-flow: column nowrap;
flex-flow: row-reverse wrap-reverse;
}Real-World Patterns
Navigation with Wrapping
.nav {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px 24px; /* row-gap column-gap */
}
.nav-link {
flex: 0 0 auto;
padding: 8px 0;
white-space: nowrap;
}Feature Cards
.features {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: stretch;
}
.feature-card {
flex: 1 1 280px;
max-width: 400px;
display: flex;
flex-direction: column;
}
.feature-card-content {
flex: 1; /* Fills remaining space */
}Centered Content Block
.centered-section {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
gap: 40px;
min-height: 80vh;
padding: 40px;
}
.centered-section > * {
flex: 0 1 500px;
}Summary
Flex-wrap transforms Flexbox from a single-line layout tool into a powerful system for responsive, multi-line layouts. Understanding how align-content controls line distribution, while justify-content and align-items handle item positioning, gives you complete control over wrapped flex layouts. These patterns form the foundation for responsive card grids, navigation systems, and adaptive content layouts that gracefully handle any amount of content on any screen size.