flex-grow, flex-shrink, flex-basis and flex-wrap

โ–ถ Try It Yourself

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
Note: 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.
Tip: For a responsive auto-wrapping card grid with no media queries: set 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.
Warning: When using 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; }

▶ Try It Yourself

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

🧠 Test Yourself

A flex item has flex: 0 0 250px. What does this mean?





โ–ถ Try It Yourself