Back to Blog
By AriesZhou · · 3 min read

Flexbox: flex-grow and flex-shrink

CSS

You set flex: 1 on three child elements, yet they do not divide the available space equally. Or an important button gets squeezed out of view on a narrow screen. Both problems come down to flex-grow and flex-shrink.

flex-grow: How extra space is distributed

When the container has leftover space, flex-grow determines how child elements “compete” for that space.

.container {
  display: flex;
  width: 500px;  /* 容器宽度 */
}

.item {
  width: 100px;  /* 每个元素基础宽度 */
}
/* 500 - 100*3 = 200px 剩余空间 */

Core rules

  • The default value is 0, meaning “don’t grow”
  • The larger the value, the more space it gets
  • Distribution formula: item's grow factor / sum of all grow factors
/* 场景:容器 500px,三个子元素各 100px,剩余 200px */

.item1 { flex-grow: 1; }  /* 1/(1+2+3) = 1/6 * 200 = 33px */
.item2 { flex-grow: 2; }  /* 2/6 * 200 = 67px */
.item3 { flex-grow: 3; }  /* 3/6 * 200 = 100px */

/* 最终宽度:133px, 167px, 200px */

Example: Holy Grail layout

.header {
  flex-grow: 0;  /* 不增长 */
}

.content {
  flex-grow: 1;  /* 中间内容区占满剩余空间 */
}

.sidebar {
  flex-grow: 0;  /* 不增长 */
}
<nav class="header">Header</nav>
<main class="content">Main Content</main>
<aside class="sidebar">Sidebar</aside>

flex-shrink: How items shrink when space is insufficient

When the container doesn’t have enough space, flex-shrink determines who “sacrifices” more.

.container {
  display: flex;
  width: 300px;  /* 容器宽度 */
}

.item {
  width: 150px;  /* 每个元素基础宽度 */
}
/* 150*3 = 450px > 300px,需要收缩 150px */

Core rules

  • The default value is 1, meaning “can shrink”
  • Set it to 0 to mean “never shrink”
  • The larger the value, the more it shrinks
/* 场景:容器 300px,三个子元素各 150px,超出 150px */

.item1 { flex-shrink: 1; }  /* 收缩 30px */
.item2 { flex-shrink: 2; }  /* 收缩 60px */
.item3 { flex-shrink: 0; }  /* 不收缩 */

/* 收缩计算:150 / (1+2+0) = 50px 每份 */

Scenario: Preventing critical content from being compressed

.button-primary {
  flex-shrink: 0;  /* 按钮不收缩,保证可点击 */
  padding: 12px 24px;
  background: #0070f3;
  color: white;
  border-radius: 6px;
}

.text-content {
  flex-shrink: 1;  /* 文字区域可以收缩 */
}
<div class="card">
  <span class="text-content">很长的文字内容...</span>
  <button class="button-primary">提交</button>
</div>

The flex shorthand

In everyday development, you usually use the flex shorthand:

/* flex: <flex-grow> <flex-shrink> <flex-basis> */

flex: 1;        /* 1 1 0% - 平均分配空间 */
flex: 1 0;      /* 1 0 0% - 只增长不收缩 */
flex: 0 1 auto; /* 0 1 auto - 默认值,等价于 0 1 auto */
flex: auto;     /* 1 1 auto - 可增长可收缩 */
flex: none;     /* 0 0 auto - 不增长不收缩 */

Common combinations and use cases

SyntaxEffectUse case
flex: 1Distribute evenlyNavigation menus, equal-width cards
flex: 0 0 200pxFixed widthSidebars, fixed-width columns
flex: autoAdaptiveLayouts where content length varies
flex: noneFixed sizeButtons, icons, etc.

Complete example: Three-column layout

.layout {
  display: flex;
  height: 100vh;
}

.sidebar-left {
  width: 200px;
  flex-shrink: 0;  /* 固定宽度不收缩 */
}

.content {
  flex: 1;         /* 占据剩余空间 */
}

.sidebar-right {
  width: 200px;
  flex-shrink: 0;
}
<div class="layout">
  <aside class="sidebar-left">左侧边栏</aside>
  <main class="content">主内容区</main>
  <aside class="sidebar-right">右侧边栏</aside>
</div>

Pitfalls

  1. flex-basis priority

    .item {
      width: 100px;
      flex-basis: 200px;  /* 实际生效的是 200px */
    }
  2. Content overflow can spill out

    .item {
      flex-shrink: 0;  /* 设为 0 防止被压缩 */
      overflow: hidden; /* 溢出隐藏 */
    }
  3. flex: 1 vs flex: auto

    /* flex: 1 - 基准值是 0%,会压到最小内容宽度 */
    /* flex: auto - 基准值是元素内容,会保留内容宽度 */

Summary

  • flex-grow: Container has extra space → how to divide it
  • flex-shrink: Container lacks space → how to shrink
  • Common combinations: flex: 1 for equal distribution, flex: 0 0 <fixed-size> for a fixed width

One principle: if you want an element to flex, use flex: 1; if you want it to stay fixed, use flex-shrink: 0.