flex: 1 应该算是 Flexbox 里最常见、也最“用着用着就忘了它到底干了啥”的写法之一。你会在各种地方见到它:

  • 三栏布局想让中间自适应
  • 一排按钮想均分宽度
  • 页面里左边固定、右边填满

它看起来像“把剩余空间全吃掉”,但背后其实是三个属性的组合。

1
2
3
.item {
flex: 1;
}

下面我们把它拆开看。

flex 属性的简写

flex 是一个简写属性,它同时设置三个属性值:

  • flex-grow
  • flex-shrink
  • flex-basis

当我们写下 flex: 1; 时,浏览器实际上将其解析为:

1
2
3
4
5
6
flex: 1 1 0%;

// 对应属性为
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
  1. flex-grow: 1
    flex-grow 定义了元素在父容器中如何分配剩余空间。设置为 1 意味着该元素可以等比例扩展,填充容器中剩余的可用空间。

  2. flex-shrink: 1
    flex-shrink 定义了元素在父容器空间不足时如何缩小。设置为 1 表示该元素可以以与其他元素相同比例收缩。

  3. flex-basis: 0%
    flex-basis 决定了“参与分配前的起步宽度”。0% 的含义可以粗暴理解成:先别管内容本身有多宽,先从 0 开始算,剩下的空间按 grow 分

这也是为什么 flex: 1 经常能实现“均分宽度”:大家都从 0 起步,再按比例分剩余空间。

小提醒:如果你希望“内容尺寸优先,再去分剩余空间”,一般会更偏向 flex: 1 1 auto(或者直接写 flex: 1 以外的组合)。

flex: 1 的实际效果

flex: 1 应用到多个子元素上时,这些子元素会按照相同比例扩展和收缩,从而平分父容器中所有可用的剩余空间。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flex: 1 示例</title>
<style>
.container {
display: flex;
width: 600px;
border: 1px solid #ccc;
}
.item {
flex: 1;
padding: 20px;
text-align: center;
border-right: 1px solid #ddd;
}
.item:last-child {
border-right: none;
}
</style>
</head>
<body>
<div class="container">
<div class="item">盒子 1</div>
<div class="item">盒子 2</div>
<div class="item">盒子 3</div>
</div>
</body>
</html>

在上面的例子中,容器宽度为 600px,三个子元素都设置了 flex: 1,它们会均分剩余空间(即每个盒子占据约 200px 的宽度)。如果调整容器大小,子元素的宽度会自动相应变化,保持等比例分配。

效果如下:

应用场景

使用 flex: 1 的场景非常广泛,尤其适用于以下情况:

  • 响应式布局:让多个子元素平分父容器中的空间,不论父容器的宽度如何变化。
  • 导航栏或工具条:多个菜单项或按钮需要均匀分布。
  • 卡片或列表项布局:在网格布局中保证卡片或列表项宽度一致,适应不同设备。

如果你只记一个结论:flex: 1 适合“均分/填满剩余空间”的场景;当你遇到“内容被挤得太小/不按内容宽度来”时,优先检查 flex-basis,很多时候把 0% 换成 auto,布局就顺了。

Happy Coding!