第12天:CSS(一)| Flexbox 布局完全指南

今天系统复习了 Flexbox 的核心属性,包括主轴与交叉轴、对齐方式、弹性伸缩计算、三栏布局实战、换行与多行对齐、以及 align-self 和 order 的进阶用法。以下是当天的问答整理与知识总结。


一、Flexbox 基础:主轴与交叉轴

1. 主轴方向 与 flex-direction

| 属性值 | 主轴方向 | 交叉轴方向 |
| row | 水平从左到右 | 垂直从上到下 |
| row-reverse | 水平从右到左 | 垂直从上到下 |
| column | 垂直从上到下 | 水平从左到右 |

column-reverse 垂直从下到上 水平从左到右

注意: justify-content 控制主轴 对齐,align-items 控制交叉轴对齐。当 flex-direction 改变时,主/交叉轴的方向随之改变。

2. 主轴对齐:justify-content

  • flex-start:起始位置对齐
  • flex-end:结束位置对齐
  • center:居中对齐
  • space-between:两端对齐,中间间距相等
  • space-around:每个子项左右边距相等,相邻子项间距是子项到父容器边距的两倍
  • space-evenly:所有间距(包括两端)完全相等

3. 交叉轴对齐:align-items

  • stretch(默认):子项在交叉轴方向拉伸填满容器(前提:子项未设置交叉轴方向的尺寸
  • flex-start / flex-end / center:与主轴类似,但方向为交叉轴
  • baseline:根据子项的文字基线对齐

stretch 的细节:

在 flex-direction: row 下,交叉轴是垂直方向,stretch 会让子项高度填满父容器;在 column 下,交叉轴是水平方向,stretch 会让子项宽度填满父容器。若子项已设置具体高度/宽度,则 stretch 失效。


二、弹性伸缩计算:flex-growflex-shrink

1. flex-grow:分配剩余空间

公式:

子项最终宽度 = 子项基础宽度 + (子项 grow / 所有子项 grow 之和) × 剩余空间

示例: 三个子项基础宽度均为 100px,父容器宽 600px,剩余空间 300px。若 flex-grow 分别为 1、2、3,则:

  • 总 grow = 6
  • 子项1 增加:300 × (1/6) = 50px → 最终 150px
  • 子项2 增加:300 × (2/6) = 100px → 最终 200px
  • 子项3 增加:300 × (3/6) = 150px → 最终 250px

2. flex-shrink:处理溢出空间

当子项总宽度超过父容器时,按比例缩小。

公式:

每个子项的权重 = 自身宽度 × 自身 shrink

总权重 = 所有子项权重之和

子项缩小宽度 = 溢出宽度 × (子项权重 / 总权重)

示例: 三个子项基础宽度分别为 100px 200px 300px,父容器宽 500px,溢出 100px。

若 flex-shrink 分别为 1、2、3,则:

  • 总权重:100 * 1 + 200 * 2 + 300 * 3 = 1400
  • 子项1 缩小:100 × (100 * 1 / 1400) ≈ 7.14px
  • 子项2 缩小:100 × (200 * 2 / 1400) ≈ 28.57px
  • 子项3 缩小:100 × (300 * 3 / 1400) ≈ 64.29px

注意:

  • flex-shrink: 0 表示该子项不允许收缩。
  • min-width / max-width 优先级高于 flex 伸缩计算,会限制最终尺寸。

3. flex 简写

  • flex: 1 → flex-grow: 1; flex-shrink: 1; flex-basis: 0%
  • flex: auto → flex-grow: 1; flex-shrink: 1; flex-basis: auto
  • flex: none → flex-grow: 0; flex-shrink: 0; flex-basis: auto

对比举例:

**a. 统一条件:**父容器宽度:600px;子 1:width: 100px;子 2:width: 200px

b. flex: 1

  • 基础尺寸 0,完全按比例分父容器
  • 两个都 flex:1 → 直接平分 600px
  • **结果:**子 1:300px;子 2:300px

c. flex: auto

  • 基础尺寸 = 自己的 width:100、200
  • 剩余空间:600 - 300 = 300px
  • 两人平分剩余,各 +150
  • 子 1:100 + 150 = 250px;子 2:200 + 150 = 350px

d. flex: none

  • 不长大(grow:0)
  • 不缩小(shrink:0)
  • 尺寸就用自己 width:100、200

三、实战:三栏布局

经典圣杯/双飞翼布局(Flex 版)

css 复制代码
.container {
  display: flex;
}
.left, .right {
  width: 200px;
  flex-shrink: 0;   /* 防止压缩 */
}
.center {
  flex: 1;          /* 占据剩余空间 */
  min-width: 150px; /* 最小宽度限制 */
  max-width: 300px; /* 最大宽度限制 */
}

说明:

  • 左右固定宽,中间自适应
  • flex-shrink: 0 保证左右在容器缩小时不会变形(默认为1,所以需要手动限制)
  • min-width 限制中间区域的最小宽度,防止被过度压缩。
  • max-width 限制中间区域的最大宽度,防止过大。

补充:

  • min-width: 0 是一个专门解除 flex 子项默认限制的 CSS 属性。(flex 默认 min-width: auto;)

  • 解除内容对宽度的 "下限锁定",让 flex-shrink 规则真正生效

  • 只有设置了 min-width: 0,text-overflow: ellipsis 才能在 flex:1 的元素上正常工作

  • 防止布局溢出: 确保子项宽度始终被限制在父容器内部

    css 复制代码
    /* 父容器 */
    .flex-container {
      display: flex;
      width: 200px; /* 父容器很窄 */
    }
    
    /* 子项 */
    .flex-item {
      flex: 1; /* 想要自适应 */
      min-width: 0; /* 关键!不加则会被内容撑宽 */
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis; /* 才能生效 */
    }

四、换行与多行对齐

1. flex-wrap: wrap 的作用

当子项总宽度超过容器时,允许换行。换行后,容器变为多行结构。

2. align-content vs align-items

| 属性 | 作用范围 | 生效条件 |
| align-items | 单行内的每个子项 | 永远生效 |

align-content 多行之间的整体对齐 必须有多行(flex-wrap: wrap 且实际换行),且交叉轴方向有剩余空间

**取值:**flex-start、flex-end、center、space-between、space-around、stretch(默认)。

3. justify-content 在多行中的行为

即使换行,justify-content 仍然作用于每一行内部,而不是整个多行容器。


五、子项个性:align-self 与 order

1. align-self

覆盖父级 align-items 的设置,允许单个子项在交叉轴上有不同的对齐方式。

**应用场景:**例如导航栏中,大部分子项垂直居中,但 logo 需要顶部对齐,可对 logo 设置 align-self: flex-start。

2. order

定义子项的排列顺序,数值越小越靠前。默认值为 0,可负值。

  • 相同 order 值时,按 DOM 顺序排列。
  • 仅改变视觉顺序,不影响 DOM 结构,对无障碍和键盘导航可能有影响。

六、常见追问

1. 如果 flex-direction: column-reverse,justify-content: flex-start 会让子项从哪里开始排列?

答:主轴垂直从下到上,flex-start 会在容器底部开始排列。

2. align-items: stretch 什么时候会失效?

答:当子项在交叉轴方向设置了具体尺寸(如 height 或 width)时。

3. flex: 1 和 flex: auto 有什么区别?

答:flex: 1 的 flex-basis: 0%,表示子项从 0 开始分配剩余空间;flex: auto 的 flex-basis: auto,表示子项先以其内容或宽度为基础,再分配剩余空间。

4. 如果一个子项设置了 flex: 1 和 max-width: 300px,父容器宽度 1000px,其他子项固定宽 100px,那么这个子项最终宽度是多少?

答:首先计算剩余空间:1000 - 200 = 800px。该子项 grow 为 1,其他固定宽子项 grow 为 0,所以它独占剩余空间,理论宽度为 0 + 800 = 800px,但受 max-width: 300px 限制,最终宽度为 300px。(右片区域一大片空白)

相关推荐
To_OC4 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic4 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy4 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志5 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble6 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯7 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜7 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司7 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g8 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森8 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http