【CSS】Flex布局

29 阅读12分钟

📐 Flex 布局基础笔记

1️⃣ 设置 Flex 容器

article {
    border: solid 5px blueviolet;
    width: 500px;
    display: flex;               /* 启用弹性布局 */
    flex-direction: column-reverse; /* 子元素垂直排列,且顺序反转 */
}

说明:

  • display: flex 必须设置在 父元素 上,表示该容器启用 Flex 布局。
  • flex-direction 控制子元素的主轴排列方向:
    • row:默认值,主轴为水平方向,元素从左到右排列。
    • row-reverse:主轴水平,元素从右到左排列。
    • column:主轴为垂直方向,元素从上到下排列。
    • column-reverse:主轴垂直,元素从下到上排列。
article * {
    width: 100px;
    height: 100px;
    background: red;
    font-size: 25px;
}
<article>
    <div>1</div>
    <div>2</div>
    <div>3</div>
</article>

2️⃣flex-wrap

当一行放不下所有子元素时,默认不会自动换行。可以使用 flex-wrap 属性设置是否换行。

article {
    display: flex;
    flex-wrap: wrap; /* 启用换行 */
}

常用取值:

  • nowrap(默认):不换行,元素可能会压缩。
  • wrap:超出宽度后自动换行,下一行从左往右。
  • wrap-reverse:换行方向相反,下一行从下往上。

3️⃣ flex-flow

flex-flowflex-directionflex-wrap 的快捷写法:

article {
    display: flex;
    flex-flow: row wrap-reverse;
}

等价于:

article {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap-reverse;
}

✅ 总结

属性作用常见取值
display设置为 flex 启用布局flex, inline-flex
flex-direction主轴方向row, row-reverse, column, column-reverse
flex-wrap是否换行nowrap, wrap, wrap-reverse
flex-flow组合方向和换行属性如:row wrap

4️⃣justify-content

justify-content 是 Flex 布局中用于控制 主轴(flex-direction)方向上的对齐方式。它决定 子元素在主轴上的分布方式

🔧 语法位置(写在父元素上):

article {
    display: flex;
    flex-direction: column;      /* 主轴为垂直方向 */
    justify-content: space-evenly; /* 控制主轴上的分布方式 */
}

📐 常用取值及效果:

含义说明效果示意(以垂直方向为例)
flex-start元素靠近主轴起点(垂直时靠顶部)🔼🔼🔼
flex-end元素靠近主轴终点(垂直时靠底部)🔽🔽🔽
center元素整体居中分布🔼🔼🔼
space-between第一个和最后一个元素贴边,中间元素平均分布🔼 🔼 🔼
space-around每个元素两边有相等间距(边缘与中间距离不一致)🔼 🔼 🔼
space-evenly所有间距都相等,包括元素之间和边缘之间🔼 🔼 🔼(等距)

✅ 小结

  • justify-content 决定了子元素在 主轴方向 的排布方式;
  • 配合 flex-direction 使用,实际排列方向可变;
  • space-evenly 是最均匀的分布方式,适合对称美观的布局场景。

5️⃣align-items


📌作用

align-items 控制 交叉轴方向(即与主轴垂直的方向)上,子元素的对齐方式。

简单说:

  • 如果 flex-direction: row,主轴是水平方向,交叉轴是垂直方向(上下对齐)
  • 如果 flex-direction: column,主轴是垂直方向,交叉轴是水平方向(左右对齐)

🔧 语法位置(写在父容器上):

article {
    display: flex;
    flex-direction: column;   /* 主轴为纵向,则align-items 控制的是横向对齐 */
    align-items: center;      /* 子元素在水平方向上居中 */
}

📐 常用取值及效果:

含义说明效果(以 flex-direction: column 为例)
stretch (默认)子元素撑满交叉轴(如果没有设置宽/高)🔲🔲🔲(每个都占满一行的宽度)
flex-start子元素在交叉轴起点对齐(左对齐)🔳
flex-end子元素在交叉轴终点对齐(右对齐)🔳
center子元素在交叉轴居中(水平居中)🔳
baseline多行文字时,按文字基线对齐(多用于文本)📐📏(文字对齐)

🧪 示例:垂直排列 + 横向居中

article {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    align-items: center;  /* 水平居中对齐 */
}

此时效果是:

  • 3 个元素在 垂直方向 上平均分布(justify-content: space-evenly
  • 同时在 水平方向 居中对齐(align-items: center

✅ 小结对比justify-content vs align-items

属性控制方向控制什么
justify-content主轴方向子元素分布位置(比如上下间距)
align-items交叉轴方向子元素对齐方式(比如左中右)

6️⃣align-content

它是 Flex 布局中一个比较容易和 align-items 混淆的属性,适合在多行布局时使用。

📌 作用:

align-content 控制 多行 Flex 子元素之间,在 交叉轴方向上的整体对齐方式

⚠️ 生效前提:必须发生 换行(即设置了 flex-wrap: wrap),且子元素排列成了多行。

🆚 和 align-items 的区别:

属性名控制对象控制范围生效条件
align-items每一行的子元素单行内部对齐无需换行也有效
align-content所有行多行之间的整体对齐必须设置 flex-wrap

🔧 语法示例:

.container {
    display: flex;
    flex-wrap: wrap;         /* 开启换行 */
    align-content: center;   /* 多行整体在交叉轴方向居中 */
    height: 400px;           /* 设置高度才能看出上下对齐差异 */
}

📐 常见取值与效果:

含义说明
stretch (默认)多行元素均匀分布,撑满容器高度
flex-start多行从交叉轴起点对齐(顶部)
flex-end多行从交叉轴终点对齐(底部)
center多行整体垂直居中
space-between首行顶端对齐,末行底部对齐,行间平均分布
space-around行与行之间的间距相等
space-evenly所有间距(含边距)完全相等

🧪 示例代码:

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

.container {
  display: flex;
  flex-wrap: wrap;
  height: 300px;
  align-content: space-around;
}

.container div {
  width: 100px;
  height: 50px;
  margin: 5px;
  background: tomato;
}

✅ 小结:

  • align-items 控制的是 每一行的元素在交叉轴方向的对齐
  • align-content 控制的是 所有行之间在交叉轴上的整体分布
  • 适用于内容换行、布局较复杂的情况(例如卡片瀑布流或响应式栅格布局)。

7️⃣align-self

📌 作用:

align-self 用于覆盖父容器中 align-items 的设置,让某个子元素在交叉轴上单独对齐

✅ 适用于需要让个别元素位置与其他不一致时使用。

🧩 使用条件:

  • 父容器必须是 display: flex
  • 子元素才可以设置 align-self
  • 覆盖父容器中统一的 align-items 设置。

📐 常见取值与说明:

含义效果(在 flex-direction: row 下示意)
auto默认值,继承父容器的 align-items与其它元素一致
flex-start交叉轴起点对齐(上/左)子元素靠上
flex-end交叉轴终点对齐(下/右)子元素靠下
center交叉轴方向居中子元素上下居中
baseline按文字基线对齐(多用于文本)字体基线对齐
stretch默认:若未设置交叉轴尺寸,则拉伸子元素在高度方向拉伸(如未指定 height)

🔧 示例代码:

        article{
            border: solid 5px blueviolet;
            width: 550px;
            height: 250px;
            display: flex;
            flex-direction: row;
            align-items: flex-end;
        }

        article :first-child{ 
            align-self: flex-start;
        }

        article :nth-child(2){ 
            align-self: center;
        }
    <article>
        <div>1</div>
        <div>2</div>
        <div>3</div>
    </article>

🎯 对比总结:

属性用于谁?控制什么?
align-items父容器所有子元素的交叉轴对齐方式
align-self单个子元素单个元素的交叉轴对齐方式

✅ 小技巧:

  • align-self 很适合做突出对齐、标记异常位置元素的样式调整;
  • 可与动画搭配,比如 transformtransition 做跳跃、弹出效果。

8️⃣flex-grow

📌 作用:

flex-grow 定义了 当主轴方向上有剩余空间时,元素能“放大”多少,即按比例分配剩余空间


🔧 用法位置:

写在 子元素 上,而不是父容器:

css
.item {
  flex-grow: 1;
}

🧮 原理理解:

  • 默认值是 0:表示不放大(不抢空间)
  • 如果多个子元素设置了 flex-grow,它们会按比例分配剩余空间

📦 flex-grow 实战笔记(按比例分配剩余空间)

💡 场景说明:

父容器宽度为 550px,每个模块初始宽度都为 100px,三个模块设置如下:

				article div:nth-child(1){
            flex-grow: 0;
        }

        article div:nth-child(2){
            flex-grow: 1;
        }

        article div:nth-child(3){
            flex-grow: 3;
        }

✏️ 步骤计算:

  1. 初始占用空间: 每个模块初始宽度是 100px,3 个模块共占: 100 * 3 = 300px
  2. 剩余空间: 容器总宽度 550px - 初始占用 300px = 剩余空间 250px
  3. 总份数(权重): 只有模块2和模块3设置了 flex-grow,所以总份数是: 1(模块2)+ 3(模块3) = 4份
  4. 每份是多少: 250px ÷ 4份 = 62.5px

📐 最终宽度计算:

模块初始宽度分得份数分得宽度最终宽度
模块1100px00px100px
模块2100px162.5px162.5px
模块3100px362.5×3287.5px

✅ 小结:

设置效果说明
flex-grow: 0不扩展,保持原始宽/高
flex-grow: 1如果有剩余空间,按比例扩展
flex-grow: N多个元素按比例抢剩余空间(N 为任意数)

🔁 常与以下属性一起使用:

  • flex-shrink: 控制缩小比例
  • flex-basis: 控制初始主轴尺寸
  • flex: 简写属性(例:flex: 1 0 100px;

9️⃣flex-shrink

📌 作用:

flex-shrink 控制当父容器空间不足时,子元素如何按比例缩小自身尺寸,防止溢出。


🧩 适用场景:

  • 元素宽度固定,但容器变窄,空间不够用了;
  • 想控制哪些元素优先缩,哪些不缩。

🧮 使用原理说明:

  1. 所有子元素会根据它们的 flex-shrink 值,按比例缩小
  2. 默认值是 1:允许缩小;
  3. 设置为 0:禁止缩小(元素会溢出容器);
  4. 多个元素缩小比例按 shrink 总值分配。

💡 场景说明:

  • 父容器宽度:400px
  • 子元素初始宽度:每个 200px
  • 子元素共计:200px × 3 = 600px
  • 需要压缩的空间:600 - 400 = 200px

🧾 样式设置:

article div:nth-child(1) {
  flex-shrink: 0;  /* 不允许缩小 */
}
article div:nth-child(2) {
  flex-shrink: 1;  /* 缩小1份 */
}
article div:nth-child(3) {
  flex-shrink: 3;  /* 缩小3份 */
}

📐 缩小计算过程:

✅ 1. 哪些元素要缩?

  • 模块1 设置 flex-shrink: 0不缩小
  • 模块2 和 模块3 一共需要缩小 200px,总权重 = 1 + 3 = 4份

✅ 2. 每份缩小多少?

复制编辑
200px ÷ 4份 = 50px / 每份

✅ 3. 分配计算:

模块初始宽度shrink 值缩小份数实际缩小最终宽度
模块1200px000px200px
模块2200px11份50px150px
模块3200px33份150px50px

✅ 结果合计:

模块1:200px  
模块2:150px  
模块3:50px  
总计:400px(与父容器宽度一致)

✨ 视觉印象总结:

模块编号是否可缩小缩得多还是少最终宽度变化
第1个❌ 不缩🚫 不变固定200px
第2个✅ 可缩🟡 缩少一点剩150px(比原少50)
第3个✅ 可缩🔴 缩最多只剩50px(比原少150)

🎯 实用总结:

  • 容器变窄时,使用 flex-shrink 可控制谁该优先让位;
  • 设置为 0 的元素可保持大小稳定;
  • 多个元素可按份数合理压缩,避免视觉突兀。

✅ 小结:

设置效果说明
flex-shrink: 0不允许缩小,可能会超出容器
flex-shrink: 1默认允许按比例缩小
flex-shrink: N数值越大,空间不足时越容易缩小

✅ 常配合使用:

flex: 1 1 auto;
/* 表示:grow = 1, shrink = 1, basis = auto */

🔟flex-basis

📌 作用:

flex-basis 用于设置元素在主轴上的初始大小(占据空间),它是 Flex 子项的“基础尺寸”。


✅ 它和 width/height 的区别:

  • width 是常规盒模型的宽度;
  • flex-basis 是 Flex 布局下,元素参与计算伸缩(grow/shrink)时的起点
  • 若同时存在,flex-basis 优先生效

🧾 属性语法:

.item {
  flex-basis: 200px; /* 设置初始主轴长度为200px */
}

也可以用百分比或 auto

flex-basis: 50%;    /* 父容器宽度的50% */
flex-basis: auto;   /* 默认大小(通常是内容或 width) */

🧮 示例说明:

场景设定:

<div class="container">
  <div class="item a">A</div>
  <div class="item b">B</div>
</div>


.container {
  display: flex;
  width: 600px;
}

.item {
  flex-grow: 1;
}

.a {
  flex-basis: 200px;
}

.b {
  flex-basis: 100px;
}

计算过程:

  1. flex-basis 空间 = 200 + 100 = 300px
  2. 剩余空间 = 600 - 300 = 300px
  3. 每个都 flex-grow: 1,平均分配 300px 的剩余空间

最终宽度:

  • A:200 + 150 = 350px
  • B:100 + 150 = 250px

🧠 与 flex 简写配合:

复制编辑
.item {
  flex: 1 1 200px;
}

表示:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 200px

✅ 常见值说明:

含义说明
auto默认值,等同于内容宽度或 width
0从 0 开始计算,常与 flex-grow 配合
px/%固定基础宽度

🎯 使用建议:

  • 想让某个子元素“从特定宽度起开始伸缩”,就设置 flex-basis
  • 如果希望等分空间,但不想考虑内容长度,可以配合 flex-basis: 0
  • 多用于构建卡片栅格、响应式布局、按钮组等。

🔍 flex: <flex-grow> <flex-shrink> <flex-basis>

这个是 flex 简写属性的结构:

flex: grow shrink basis;
flex: 1 1 200px;

等价于:

  • flex-grow: 1:可以增长(多分一点空间)
  • flex-shrink: 1:可以收缩(空间不够时允许缩小)
  • flex-basis: 200px:基础宽度为 200px

✅ 总结一下(通俗解释)

属性意义
flex-grow空间多了,谁能多分一点?(比例)
flex-shrink空间不够,谁愿意多缩一点?(比例)
flex-basis默认宽度是多少?(一开始的尺寸)

11.order

📌 作用:

order 控制 Flex 容器中的子元素排序顺序,与它在 HTML 中的实际书写顺序无关。

🧾 属性语法:

.item {
  order: 1; /* 数值越小越靠前,默认是 0 */
}

🧠 默认值:

order: 0;  /* 所有元素默认的顺序都是 0 */
  • 数字可以是正数、负数、小数;
  • 数字越小,位置越靠前
  • 可以完全打乱原有 HTML 顺序。

📐 示例说明:

HTML 结构:

<article>
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</article>

CSS 设置:

.a { order: 2; }
.b { order: 1; }
.c { order: -1; }

实际显示顺序:

C(order -1) → B(order 1) → A(order 2)

✅ 实用技巧:

使用场景示例
表单中想让提交按钮移到前面给按钮设置 order: -1
响应式布局中移动图片到最底部在小屏幕时修改 order
排序可视化组件用 JS 动态修改 order

⚠️ 注意:

  • order 只在 Flex 或 Grid 布局中生效;
  • 同一个 order 值的元素将按照 HTML 原顺序排列;
  • 不会影响 DOM 结构或无障碍(屏幕阅读器仍按原顺序读)!

🎯 记忆口诀:

“数字小,站得早,数字大,排队靠后。”