CSS Flex 布局中 `flex` 属性深入解析

flex 是 Flex 布局中核心的复合属性 ,用于控制弹性项目(flex item)在弹性容器(flex container)中的伸缩规则 ,它是 flex-growflex-shrinkflex-basis 三个子属性的简写,语法为:

css 复制代码
flex: [flex-grow] [flex-shrink] [flex-basis];

默认值:flex: 0 1 auto(即 flex-grow:0flex-shrink:1flex-basis:auto)。


一、先理解三个子属性的独立作用

1. flex-grow:扩展因子(放大比例)

  • 作用 :当弹性容器有剩余空间时,项目是否/如何瓜分剩余空间。
  • 取值 :非负数字(无单位),默认 0
  • 规则
    • flex-grow: 0:不参与剩余空间分配(默认行为);
    • flex-grow: n(n>0):项目按比例瓜分剩余空间,总份数为所有项目 flex-grow 之和,单个项目占比 = 自身 flex-grow / 总份数。
  • 示例
    容器宽度 500px,包含 3 个项目,宽度分别为 100px、100px、100px,剩余空间 = 500 - 300 = 200px。
    • 项目1:flex-grow: 1,项目2:flex-grow: 2,项目3:flex-grow: 1 → 总份数 4;
    • 项目1 分配:200 * (1/4) = 50px → 最终宽度 150px;
    • 项目2 分配:200 * (2/4) = 100px → 最终宽度 200px;
    • 项目3 分配:200 * (1/4) = 50px → 最终宽度 150px。

2. flex-shrink:收缩因子(缩小比例)

  • 作用 :当弹性容器空间不足(项目总宽度 > 容器宽度)时,项目是否/如何被压缩。
  • 取值 :非负数字(无单位),默认 1
  • 规则
    • flex-shrink: 0:不压缩,项目保持 flex-basis 宽度(可能溢出容器);
    • flex-shrink: n(n>0):项目按「flex-shrink * flex-basis」的比例被压缩(核心:不是直接按 flex-shrink 比例,而是结合基准宽度)。
  • 示例
    容器宽度 300px,包含 2 个项目:
    • 项目1:flex-basis: 200px; flex-shrink: 1
    • 项目2:flex-basis: 200px; flex-shrink: 2
    • 总溢出:400 - 300 = 100px;
    • 压缩权重总和:(2001) + (2002) = 600;
    • 项目1 压缩:100 * (200*1)/600 ≈ 33.33px → 最终宽度 166.67px;
    • 项目2 压缩:100 * (200*2)/600 ≈ 66.67px → 最终宽度 133.33px。

3. flex-basis:基准宽度

  • 作用 :定义项目在「伸缩前」的初始宽度(优先级高于 width/height,前提是 flex 主轴为水平/垂直)。
  • 取值
    • auto:默认,取项目自身的宽度(若未设置 width,则为内容宽度);
    • 具体数值(如 100px20%):固定基准宽度;
    • 0:基准宽度为 0,此时 flex-grow 分配的是「纯剩余空间」(而非「剩余空间+项目宽度」)。
  • 关键区别flex-basis: auto vs flex-basis: 0
    容器宽度 500px,2 个项目都设 flex-grow: 1
    • 项目1/2 无宽度,flex-basis: auto → 基准宽度为内容宽度(假设各 50px),剩余空间 500-100=400px,各分 200px → 最终宽度 250px;
    • 项目1/2 flex-basis: 0 → 基准宽度 0,剩余空间 500px,各分 250px → 最终宽度 250px(看似结果相同,但逻辑不同);
      若项目有固定宽度(如 width: 100px):
    • flex-basis: auto → 基准宽度=100px,剩余空间 500-200=300px,各分 150px → 最终 250px;
    • flex-basis: 0 → 基准宽度=0,剩余空间 500px,各分 250px → 最终 250px(结果仍相同,但 flex-basis:0 更「纯粹」按比例分配)。

二、flex 简写的常见取值及含义

1. 单值语法

取值 等价于 含义
flex: n flex: n 1 0% n 为正数,flex-grow:nflex-shrink:1flex-basis:0%(常用);
flex: auto flex: 1 1 auto 可伸缩、可收缩,基准宽度为自身宽度(等价于默认值改 flex-grow:1);
flex: none flex: 0 0 auto 不可伸缩、不可收缩,基准宽度为自身宽度(固定宽度,不响应容器);
flex: 100px flex: 1 1 100px 基准宽度 100px,可伸缩、可收缩;

2. 双值语法

取值 等价于 含义
flex: a b flex: a b 0% flex-grow:aflex-shrink:bflex-basis:0%
flex: a 100px flex: a 1 100px flex-grow:aflex-shrink:1flex-basis:100px

3. 三值语法

flex: grow shrink basis → 完全对应三个子属性(如 flex: 2 3 200px)。

4. 最常用的简写场景

  • flex: 1 :等价 1 1 0%,项目均分剩余空间(最常用的「等分布局」);
    示例:容器内 3 个项目都设 flex:1 → 各占 1/3 宽度;
  • flex: auto :等价 1 1 auto,项目先按自身宽度排列,剩余空间均分,不足时压缩;
  • flex: none :等价 0 0 auto,项目固定宽度(不伸缩、不收缩),溢出容器则显示滚动/溢出;
  • flex: 0 auto :等价默认值 0 1 auto,项目不放大,不足时收缩,基准宽度为自身宽度;
  • flex: 2 :等价 2 1 0%,项目占比是 flex:1 项目的 2 倍(如 2:1 分栏)。

三、关键注意事项

1. flex-basis 优先级高于 width/height

  • 若主轴为水平(flex-direction: row),flex-basis 覆盖 width
  • 若主轴为垂直(flex-direction: column),flex-basis 覆盖 height
  • 例外:flex-basis: auto 时,width/height 生效(作为基准宽度)。

2. flex-shrink: 0 防止项目被压缩

  • 场景:按钮/固定宽度元素,避免容器变窄时被挤压(如 flex: 0 0 120px);
  • 若设 flex-shrink: 0flex-basis 过大,项目会溢出容器(需配合 overflow 处理)。

3. 避免混用 flexwidth/height

  • 若已设置 flex: 1(等价 flex-basis:0%),再设 width 无意义(flex-basis 优先级更高);
  • 若需固定宽度,优先用 flex: 0 0 100px 而非 width:100px(更符合 flex 逻辑)。

4. 浏览器兼容性

  • 现代浏览器(Chrome/Firefox/Safari 9+/Edge)完全支持;
  • 旧版 IE(IE10-)需加前缀(-ms-flex),且部分属性行为不一致(建议放弃兼容)。

四、实战示例

示例1:等分三栏布局

css 复制代码
.container {
  display: flex;
  width: 100%;
  height: 200px;
}
.item {
  flex: 1; /* 等价 1 1 0%,均分宽度 */
  border: 1px solid #000;
}

示例2:固定侧边栏 + 自适应主内容

css 复制代码
.container {
  display: flex;
  width: 100%;
}
.sidebar {
  flex: 0 0 200px; /* 固定200px,不伸缩、不收缩 */
  background: #eee;
}
.main {
  flex: 1; /* 自适应剩余空间 */
  background: #fff;
}

示例3:容器不足时,部分项目不压缩

css 复制代码
.container {
  display: flex;
  width: 300px; /* 总宽度不足 */
}
.item1 {
  flex: 0 0 150px; /* 固定150px,不压缩 */
  background: #f00;
}
.item2 {
  flex: 1; /* 可压缩,占剩余空间 */
  background: #0f0;
}

总结

flex 属性的核心是「先确定基准宽度(flex-basis),再根据容器空间是否充足,通过 flex-grow 放大或 flex-shrink 缩小」:

  • 等分布局:flex: 1
  • 固定宽度:flex: 0 0 固定值
  • 自适应+可收缩:flex: auto
  • 固定不可变:flex: none
    掌握这三个子属性的交互逻辑,就能精准控制 flex 项目的布局行为。
相关推荐
Demoncode_y1 个月前
前端布局入门:flex、grid 及其他常用布局
前端·css·布局·flex·grid
我有一棵树1 个月前
使用Flex布局实现多行多列,每个列宽度相同
前端·css·html·scss·flex
!win !2 个月前
一文搞懂Flex弹性布局空间分配规则
css·flex
奶昔不会射手3 个月前
css3之flex布局
前端·css3·flex
暖木生晖4 个月前
flex-wrap子元素是否换行
javascript·css·css3·flex
前端_yu小白7 个月前
css网格布局Grid
css·flex·网格布局·grid布局
江上清风山间明月9 个月前
一周掌握Flutter开发--3、布局与 UI 组件
flutter·column·listview·flex·gridview·row·layoutbuilder
放逐者-保持本心,方可放逐1 年前
css 布局及动画应用(flex+transform+transition+animation)
前端·css·transform·animation·flex·transition·transgorm
!win !1 年前
使用Flex布局的几个小技巧
css·flex