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
0to 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
| Syntax | Effect | Use case |
|---|---|---|
flex: 1 | Distribute evenly | Navigation menus, equal-width cards |
flex: 0 0 200px | Fixed width | Sidebars, fixed-width columns |
flex: auto | Adaptive | Layouts where content length varies |
flex: none | Fixed size | Buttons, 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
-
flex-basispriority.item { width: 100px; flex-basis: 200px; /* 实际生效的是 200px */ } -
Content overflow can spill out
.item { flex-shrink: 0; /* 设为 0 防止被压缩 */ overflow: hidden; /* 溢出隐藏 */ } -
flex: 1 vs flex: auto
/* flex: 1 - 基准值是 0%,会压到最小内容宽度 */ /* flex: auto - 基准值是元素内容,会保留内容宽度 */
Summary
flex-grow: Container has extra space → how to divide itflex-shrink: Container lacks space → how to shrink- Common combinations:
flex: 1for 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, useflex-shrink: 0.