CSSflex-grow & flex-shrink

flex-grow & flex-shrink

flex-grow controls how much an item expands when there's extra space. flex-shrink controls how much an item compresses when space is tight. Both use proportional values: higher values get proportionally more/less space. Understanding these properties is key to responsive flex layouts.

flex-grow: distributing extra space

CSS
<!-- flex-grow: how item shares extra space -->
.container {
  display: flex;
  width: 600px;  /* extra space available -->
  gap: 0;
}

.item {
  flex: 0 1 auto;  /* flex-grow: 0 (doesn't grow) -->
  width: 100px;
  /* All items 100px, extra space left empty */
}

<!-- [100px] [100px] [100px] [extra 300px space] -->

/* All items grow equally -->
.container {
  display: flex;
  width: 600px;
  gap: 0;
}

.item {
  flex-grow: 1;  /* each grows equally -->
  flex-basis: 0;  /* start from 0, grow to share space -->
}

<!-- [200px] [200px] [200px] equally distributed -->

/* Different growth rates -->
.container {
  display: flex;
  width: 600px;
  gap: 0;
}

.item:nth-child(1) {
  flex: 1 1 100px;  /* grows 1 unit from 100px base -->
}

.item:nth-child(2) {
  flex: 2 1 100px;  /* grows 2 units from 100px base -->
}

.item:nth-child(3) {
  flex: 1 1 100px;  /* grows 1 unit from 100px base -->
}

<!-- Total: 1+2+1 = 4 units growth -->
<!-- Item 2 gets 2/4 (50%) of extra space -->
<!-- Items 1 & 3 each get 1/4 (25%) of extra space -->

/* One item grows, others fixed -->
.container {
  display: flex;
  width: 600px;
  gap: 0;
}

.sidebar {
  flex: 0 0 200px;  /* fixed 200px -->
}

.content {
  flex: 1;  /* takes all extra space -->
}

<!-- [200px fixed] [remaining space] -->

/* Common ratios -->
.two-column {
  flex: 2 1 0;  /* takes 2/3 -->
}

.one-column {
  flex: 1 1 0;  /* takes 1/3 -->
}
flex-shrink: handling space shortage

CSS
<!-- flex-shrink: how item compresses when cramped -->
.container {
  display: flex;
  width: 300px;  /* not enough space -->
  gap: 0;
}

.item {
  flex-basis: 100px;  /* wants 100px -->
  flex-shrink: 0;     /* won't shrink -->
}

<!-- [100px] [100px] [100px] overflow! -->

/* All items shrink equally -->
.container {
  display: flex;
  width: 300px;  /* cramped -->
  gap: 0;
}

.item {
  flex-basis: 100px;  /* wants 100px each -->
  flex-shrink: 1;     /* can shrink equally -->
}

<!-- [~75px] [~75px] [~75px] equally compressed -->

/* Different shrink rates -->
.container {
  display: flex;
  width: 300px;  /* space shortage -->
  gap: 0;
}

.important {
  flex: 0 0 150px;  /* won't shrink -->
}

.flexible {
  flex: 1 1 150px;  /* shrinks if needed -->
}

<!-- [150px fixed] [~150px shrinks] -->

/* One item protected from shrinking -->
.container {
  display: flex;
  gap: 10px;
}

.button {
  flex: 0 0 auto;  /* button size never shrinks -->
  padding: 10px 20px;
  white-space: nowrap;
}

.input {
  flex: 1;  /* input can shrink -->
  min-width: 200px;  /* but not below 200px -->
}
Practical flex-grow and flex-shrink patterns

Pattern

flex Property

Behavior

Fixed item

0 0 200px

Never grows or shrinks

Growing item

1 1 0

Takes all extra space

Flexible item

1 1 auto

Flexible both ways

Protected item

0 0 auto

Content-sized, no flex

Two-to-one ratio

2 1 0 and 1 1 0

Different growth rates

CSS
<!-- Responsive sidebar layout -->
<div class="layout">
  <aside class="sidebar">Sidebar</aside>
  <main class="content">Content</main>
</div>

.layout {
  display: flex;
  gap: 20px;
  width: 100%;
}

.sidebar {
  flex: 0 1 300px;  /* starts at 300px, can shrink but not grow -->
  min-width: 250px;  /* never smaller than 250px -->
}

.content {
  flex: 1;  /* takes remaining space -->
  min-width: 400px;  /* but needs at least 400px -->
}

<!-- Sidebar flexible, content flexible, content gets priority -->

/* Three-column with different ratios -->
.three-col {
  display: flex;
  gap: 20px;
  width: 100%;
}

.col-left {
  flex: 1 1 0;  /* 1 unit -->
}

.col-middle {
  flex: 2 1 0;  /* 2 units (2x wider) -->
}

.col-right {
  flex: 1 1 0;  /* 1 unit -->
}

<!-- [25%] [50%] [25%] distribution -->

/* Toolbar with spacer -->
.toolbar {
  display: flex;
  gap: 10px;
  padding: 10px;
  border-bottom: 1px solid #ddd;
}

.tool-group {
  display: flex;
  gap: 5px;
  flex: 0 0 auto;  /* group doesn't grow -->
}

.spacer {
  flex: 1;  /* pushes following items right -->
}

.actions {
  display: flex;
  gap: 5px;
  flex: 0 0 auto;  /* actions don't grow -->
}

<!-- [tools] [spacer] [actions] -->

/* Input field with button -->
.input-group {
  display: flex;
  gap: 10px;
  width: 100%;
}

input {
  flex: 1;  /* grows to fill space -->
  min-width: 200px;
}

button {
  flex: 0 0 auto;  /* button never shrinks -->
  padding: 10px 20px;
  white-space: nowrap;
}

<!-- [input grows] [button fixed] -->
flex-grow and flex-shrink ratio calculation

CSS
<!-- How grow factors work -->
.container {
  display: flex;
  width: 900px;  /* 600px of space after 300px items -->
  gap: 0;
}

.item-a {
  flex: 1 1 100px;  /* base 100px, grow 1 -->
}

.item-b {
  flex: 2 1 100px;  /* base 100px, grow 2 -->
}

.item-c {
  flex: 1 1 100px;  /* base 100px, grow 1 -->
}

/* Total growth needed: 900-300 = 600px -->
/* Growth units: 1+2+1 = 4 total -->
/* Item A: 100 + (600 * 1/4) = 100 + 150 = 250px -->
/* Item B: 100 + (600 * 2/4) = 100 + 300 = 400px -->
/* Item C: 100 + (600 * 1/4) = 100 + 150 = 250px -->

<!-- How shrink factors work -->
.container {
  display: flex;
  width: 300px;  /* shortage of 300-300 = 0, or 100 items shortage -->
  gap: 0;
}

.item-protected {
  flex: 1 0 100px;  /* no shrink -->
}

.item-flexible {
  flex: 1 1 100px;  /* can shrink -->
}

/* Item protected stays 100px -->
/* Item flexible shrinks to fill remaining space -->
<!-- [100px] [200px after shrink] -->

/* Comparing grow vs shrink behavior -->
.container {
  display: flex;
  width: 300px;
}

.item {
  flex: 1 2 100px;
  /* flex-grow: 1 (grows 1 unit if space available) -->
  /* flex-shrink: 2 (shrinks 2 units if cramped - faster shrink) -->
}

<!-- Item shrinks faster than it grows (asymmetric) -->
Note
`flex-grow` distributes extra space proportionally. `flex-shrink` compresses items proportionally when space is tight. Use `flex: 1 1 0` for equal-width columns, `flex: 0 0 auto` for fixed items, and `flex: 1 1 auto` for flexible items that maintain content size.
Next
Flex sizing with basis: [flex-basis](/css/flex-basis).