Once you understand the flex container, the next step is controlling how individual flex items size themselves. The three properties flex-grow, flex-shrink, and flex-basis โ combined in the flex shorthand โ tell the browser how each item should behave when there is extra space or not enough space. Combined with flex-wrap, these properties let you build responsive layouts without a single media query.
flex-grow, flex-shrink, flex-basis
| Property | Default | Controls |
|---|---|---|
flex-grow |
0 โ do not grow | Proportion of available free space the item absorbs |
flex-shrink |
1 โ can shrink | Rate at which the item shrinks when container is too small |
flex-basis |
auto โ use content width | The item’s ideal starting size before flex math is applied |
flex Shorthand Cheat Sheet
| Shorthand | Expands To | Meaning |
|---|---|---|
flex: 1 |
1 1 0% | Grow and shrink equally; ignore content size when distributing space |
flex: auto |
1 1 auto | Grow and shrink; start from natural content width |
flex: none |
0 0 auto | Rigid โ never grow or shrink; always its natural size |
flex: 0 0 200px |
grow 0, shrink 0, basis 200px | Fixed 200px โ does not flex at all |
flex: 2 |
2 1 0% | Grows twice as fast as flex: 1 siblings |
flex-wrap
| Value | Behaviour | Use Case |
|---|---|---|
nowrap (default) |
All items on one line; items shrink to fit | Navbars, toolbars that must stay single-line |
wrap |
Items wrap to new lines when they would overflow | Responsive card grids, tag clouds, icon lists |
wrap-reverse |
Items wrap, but new lines appear above the previous line | Rare โ reversed pagination-style layouts |
flex: 1 uses flex-basis: 0% โ items distribute free space equally regardless of content. flex: auto uses flex-basis: auto โ items start at their natural content width then share remaining space proportionally. Choose flex: 1 for equal columns; choose flex: auto for proportional columns.display: flex; flex-wrap: wrap; on the container and flex: 1 1 260px; on items. Cards will be at least 260px wide and automatically create 1, 2, 3 or more columns based on available space.flex-wrap: wrap with flex: 1, the last row of items stretches to fill the full container width โ potentially creating a single awkwardly wide orphan card. Fix with max-width on items, or switch to CSS Grid which handles this perfectly.Basic Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-grow, shrink, basis and wrap</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; padding: 32px; background: #f8fafc; }
h3 { margin: 24px 0 8px; font-size: 0.875rem; text-transform: uppercase;
letter-spacing: 0.06em; color: #64748b; }
.row { display: flex; gap: 12px; margin-bottom: 8px; }
.box {
padding: 16px;
border-radius: 8px;
font-size: 0.8rem;
font-weight: 700;
color: white;
text-align: center;
}
/* flex: 1 โ equal share */
.f1 { flex: 1; background: #4f46e5; }
/* flex: 2 โ twice the share */
.f2 { flex: 2; background: #7c3aed; }
/* flex: none โ rigid, natural size */
.f-none { flex: none; width: 120px; background: #64748b; }
/* flex: 0 0 200px โ fixed */
.f-fixed { flex: 0 0 200px; background: #0891b2; }
/* Auto-wrap card grid */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-top: 8px;
}
.flex-card {
flex: 1 1 220px; /* grow, shrink, min ideal width 220px */
max-width: 340px; /* cap to prevent lone cards stretching wide */
background: white;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 20px;
}
.flex-card h4 { margin: 0 0 8px; color: #0f172a; }
.flex-card p { margin: 0; font-size: 0.875rem; color: #64748b; }
/* Sidebar + main with flex-basis */
.layout { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 8px; }
.layout-sidebar {
flex: 0 0 220px; /* rigid 220px sidebar */
background: #f1f5f9;
border-radius: 10px;
padding: 20px;
font-size: 0.875rem;
color: #475569;
}
.layout-main {
flex: 1 1 320px; /* takes remaining space, min 320px before wrap */
background: white;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 20px;
font-size: 0.875rem;
color: #334155;
}
</style>
</head>
<body>
<h3>flex-grow proportions</h3>
<div class="row">
<div class="box f1">flex: 1</div>
<div class="box f1">flex: 1</div>
<div class="box f2">flex: 2 (double share)</div>
</div>
<h3>flex: none and flex: 0 0 200px</h3>
<div class="row">
<div class="box f-none">flex: none (120px natural)</div>
<div class="box f-fixed">flex: 0 0 200px (fixed)</div>
<div class="box f1">flex: 1 (fills rest)</div>
</div>
<h3>Auto-wrapping card grid (resize window)</h3>
<div class="card-grid">
<div class="flex-card"><h4>Card One</h4><p>flex: 1 1 220px</p></div>
<div class="flex-card"><h4>Card Two</h4><p>flex: 1 1 220px</p></div>
<div class="flex-card"><h4>Card Three</h4><p>flex: 1 1 220px</p></div>
<div class="flex-card"><h4>Card Four</h4><p>flex: 1 1 220px</p></div>
</div>
<h3>Sidebar + main (wraps on narrow screens)</h3>
<div class="layout">
<aside class="layout-sidebar">Sidebar โ flex: 0 0 220px (rigid)</aside>
<main class="layout-main">Main content โ flex: 1 1 320px (fills remaining space)</main>
</div>
</body>
</html>
How It Works
Step 1 โ flex-grow Distributes Free Space Proportionally
In a row with two flex: 1 items and one flex: 2 item, the total grow factor is 4. Each unit of flex:1 receives 1/4 of free space; flex:2 receives 2/4. The browser calculates this after placing items at their flex-basis size.
Step 2 โ flex: none Keeps Items at Natural Size
An item with flex: none (which is flex: 0 0 auto) never grows and never shrinks. It occupies exactly its content width. Combined with flex:1 siblings, it creates a “rigid + fluid” pattern โ the rigid item stays fixed while the fluid ones absorb all size changes.
Step 3 โ flex-wrap: wrap Breaks Items Into Rows
Without wrap, all items squeeze onto one line and shrink as needed. With flex-wrap: wrap, when an item would overflow the container it wraps to a new line, creating a natural multi-row layout. Each row acts as its own flex line.
Step 4 โ flex-basis Sets the Starting Point
In flex: 1 1 220px the basis of 220px means items start at 220px before grow/shrink is applied. If the container has room for three 220px items plus gaps, three appear in a row. If only room for two, the third wraps โ no JavaScript or media queries needed.
Step 5 โ max-width Prevents Orphan Stretching
On the card grid, a lone last-row card with flex: 1 would grow to fill the entire row width. Adding max-width: 340px caps its growth โ the card stays an appropriate width and aligns to the row start.
Real-World Example: Responsive Product Grid
/* product-grid.css */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, sans-serif; background: #f8fafc; padding: 40px 24px; }
.product-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.product-card {
flex: 1 1 260px;
max-width: 320px;
background: white;
border-radius: 16px;
border: 1px solid #e2e8f0;
overflow: hidden;
display: flex;
flex-direction: column;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
transition: box-shadow 0.2s, transform 0.2s;
}
.product-card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.product-image {
height: 180px;
background: #ede9fe;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
flex-shrink: 0;
}
.product-body {
padding: 20px;
display: flex;
flex-direction: column;
flex: 1;
}
.product-name { font-size: 1rem; font-weight: 700; margin-bottom: 6px; color: #0f172a; }
.product-desc { font-size: 0.85rem; color: #64748b; line-height: 1.5; flex: 1; margin-bottom: 16px; }
.product-footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: auto;
}
.product-price { font-size: 1.2rem; font-weight: 800; color: #4f46e5; }
.add-btn {
background: #4f46e5; color: white;
border: none; padding: 8px 16px;
border-radius: 8px; cursor: pointer;
font-size: 0.85rem; font-weight: 600;
flex-shrink: 0;
}
.add-btn:hover { background: #4338ca; }
Common Mistakes
Mistake 1 โ Expecting flex-basis to act as max-width
โ Wrong โ items with flex-grow: 1 will exceed their flex-basis:
.item { flex: 1 1 200px; }
/* Items start at 200px but GROW beyond it โ not capped at 200px */
โ Correct โ add max-width to cap the maximum size:
.item { flex: 1 1 200px; max-width: 260px; }
Mistake 2 โ Forgetting flex-shrink: 0 on rigid elements
โ Wrong โ avatars and icons shrink below their declared size:
.avatar { width: 48px; height: 48px; border-radius: 50%; }
/* In a flex container with little space, this shrinks below 48px */
โ Correct โ prevent shrinking on fixed-size elements:
.avatar { width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0; }
Mistake 3 โ Using flex-wrap for precise two-dimensional grids
โ Wrong โ flex-wrap leaves orphan items stretched on the last row:
.grid { display: flex; flex-wrap: wrap; }
.grid-item { flex: 1 1 200px; }
/* 7 items, 3-per-row: last item stretches full width */
โ Correct โ use CSS Grid for strict two-dimensional layouts:
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
Quick Reference
| Shorthand | Grow | Shrink | Basis | Meaning |
|---|---|---|---|---|
flex: 1 |
1 | 1 | 0% | Equal share from zero basis |
flex: auto |
1 | 1 | auto | Proportional from content size |
flex: none |
0 | 0 | auto | Rigid โ never flex |
flex: 0 0 200px |
0 | 0 | 200px | Fixed 200px always |
flex: 1 1 260px |
1 | 1 | 260px | Fluid; min ideal 260px; wraps |