全面解析 CSS Flex 布局:从入门到精通的所有属性详解

1. Flex 容器属性

通过 display: flexdisplay: inline-flex 将元素设置为 Flex 容器。以下是所有容器属性。

1.1 display: flex | inline-flex

  • 作用:定义一个 Flex 容器。

  • 可选值

    • flex:块级容器,占据整行。
    • inline-flex:行内块容器,宽度随内容自适应。
  • 示例

    css 复制代码
    .container {
      display: flex;
    }
    .inline-container {
      display: inline-flex;
    }

    效果flex 使容器占满整行,inline-flex 宽度随内容变化。

1.2 flex-direction

  • 作用:定义主轴方向。

  • 可选值

    • row(默认):水平从左到右。
    • row-reverse:水平从右到左。
    • column:垂直从上到下。
    • column-reverse:垂直从下到上。
  • 示例

    css 复制代码
    .container {
      display: flex;
      flex-direction: column;
    }

    效果:子项垂直排列,从上到下。

1.3 flex-wrap

  • 作用:控制子项是否换行。

  • 可选值

    • nowrap(默认):单行排列,可能压缩子项。
    • wrap:多行排列,子项超出容器时换行。
    • wrap-reverse:多行排列,行顺序反转。
  • 示例

    css 复制代码
    .container {
      display: flex;
      flex-wrap: wrap;
    }

    效果:子项超出容器宽度时自动换行。

1.4 flex-flow

  • 作用flex-directionflex-wrap 的简写。

  • 语法flex-flow: <flex-direction> <flex-wrap>;

  • 示例

    css 复制代码
    .container {
      display: flex;
      flex-flow: row wrap;
    }

    效果:子项水平排列,支持换行。

1.5 justify-content

  • 作用:控制主轴上子项的对齐方式。

  • 可选值

    • flex-start(默认):靠主轴起点。
    • flex-end:靠主轴终点。
    • center:居中对齐。
    • space-between:两端对齐,间距均分。
    • space-around:子项周围间距相等。
    • space-evenly:间距完全均等。
  • 示例

    css 复制代码
    .container {
      display: flex;
      justify-content: space-between;
    }

    效果:子项两端对齐,剩余空间均分。

1.6 align-items

  • 作用:控制交叉轴上子项的对齐方式(单行)。

  • 可选值

    • stretch(默认):子项拉伸填满交叉轴。
    • flex-start:靠交叉轴起点。
    • flex-end:靠交叉轴终点。
    • center:居中对齐。
    • baseline:按文本基线对齐。
  • 示例

    css 复制代码
    .container {
      display: flex;
      align-items: center;
    }

    效果:子项在交叉轴上居中。

1.7 align-content

  • 作用 :控制多行子项在交叉轴上的对齐方式(需 flex-wrap: wrap)。

  • 可选值

    • stretch(默认):行拉伸填满交叉轴。
    • flex-start:靠交叉轴起点。
    • flex-end:靠交叉轴终点。
    • center:居中对齐。
    • space-between:两端对齐,间距均分。
    • space-around:行周围间距相等。
    • space-evenly:行间距完全均等。
  • 示例

    css 复制代码
    .container {
      display: flex;
      flex-wrap: wrap;
      align-content: space-around;
    }

    效果:多行子项在交叉轴上均匀分布。

1.8 gap, row-gap, column-gap

  • 作用:设置子项间距。

  • 可选值 :长度值(如 10px1rem)。

  • 说明

    • gap:同时设置行间距和列间距。
    • row-gap:单独设置行间距。
    • column-gap:单独设置列间距。
  • 示例

    css 复制代码
    .container {
      display: flex;
      gap: 20px;
    }

    效果:子项间水平和垂直间距为 20px。

2. Flex 子项属性

Flex 子项(容器的直接子元素)通过以下属性控制自身行为。

2.1 flex-grow

  • 作用:定义子项分配主轴剩余空间的比例。

  • 可选值 :非负整数(默认 0)。

  • 说明:值越大,子项占用剩余空间越多。

  • 示例

    css 复制代码
    .item1 {
      flex-grow: 1;
    }
    .item2 {
      flex-grow: 2;
    }

    效果item2 占用剩余空间是 item1 的两倍。

2.2 flex-shrink

  • 作用:定义子项在主轴上压缩的比例。

  • 可选值 :非负整数(默认 1)。

  • 说明:值越大,空间不足时子项压缩越多。

  • 示例

    css 复制代码
    .item1 {
      flex-shrink: 0;
    }
    .item2 {
      flex-shrink: 2;
    }

    效果 :空间不足时,item1 不压缩,item2 压缩更多。

2.3 flex-basis

  • 作用:定义子项在主轴上的初始大小。

  • 可选值 :长度值(如 100px20%)或 auto(默认)。

  • 说明 :优先级高于 widthheight

  • 示例

    css 复制代码
    .item {
      flex-basis: 200px;
    }

    效果:子项初始宽度为 200px。

2.4 flex

  • 作用flex-growflex-shrinkflex-basis 的简写。

  • 语法flex: <flex-grow> <flex-shrink> <flex-basis>;

  • 常用值

    • flex: 1:等同于 flex: 1 1 0%
    • flex: auto:等同于 flex: 1 1 auto
    • flex: none:等同于 flex: 0 0 auto
  • 示例

    css 复制代码
    .item {
      flex: 1 1 200px;
    }

    效果:子项初始宽度 200px,可伸缩。

2.5 align-self

  • 作用 :单独控制子项在交叉轴上的对齐,覆盖 align-items

  • 可选值auto(默认,继承 align-items)、flex-startflex-endcenterbaselinestretch

  • 示例

    css 复制代码
    .item {
      align-self: flex-end;
    }

    效果:该子项靠交叉轴终点对齐。

2.6 order

  • 作用:控制子项排列顺序。

  • 可选值 :整数(默认 0)。

  • 说明:值越小,子项越靠前。

  • 示例

    css 复制代码
    .item1 {
      order: 2;
    }
    .item2 {
      order: 1;
    }

    效果item2 排在 item1 之前。

3. 常见问题:flex: 1 导致无法固定宽度或高度

3.1 问题描述

使用 flex: 1(等同于 flex: 1 1 0%)时,子项会忽略显式设置的 widthheight,导致无法固定宽度或高度。这是因为:

  • flex: 1 设置了 flex-basis: 0%,使子项的初始主轴尺寸为 0,优先级高于 widthheight
  • flex-grow: 1 使子项尽可能占用剩余空间。
  • 当主轴为水平方向(flex-direction: row),width 被忽略;当主轴为垂直方向(flex-direction: column),height 被忽略。

示例(问题重现):

css 复制代码
.container {
  display: flex;
}
.item {
  flex: 1;
  width: 200px; /* 被忽略 */
  height: 100px;
}

效果 :子项宽度由剩余空间决定,width: 200px 无效。

3.2 解决方案

要固定宽度或高度,可以通过以下方式解决:

  1. 使用 flex-basis 明确指定初始尺寸

    css 复制代码
    .item {
      flex: 1 1 200px; /* flex-basis 设置为 200px */
      height: 100px;
    }

    效果:子项宽度固定为 200px,同时保持伸缩能力。

  2. 设置 flex: noneflex: 0 0 200px

    css 复制代码
    .item {
      flex: none; /* 等同于 flex: 0 0 auto */
      width: 200px;
      height: 100px;
    }

    效果:子项宽度固定为 200px,不伸缩。

  3. 使用 min-widthmax-width 限制尺寸

    css 复制代码
    .item {
      flex: 1;
      min-width: 200px;
      max-width: 200px;
      height: 100px;
    }

    效果:子项宽度固定为 200px,防止被拉伸或压缩。

  4. flex-direction: column 中固定高度

    css 复制代码
    .container {
      display: flex;
      flex-direction: column;
    }
    .item {
      flex: 0 0 100px; /* 固定高度 */
      width: 200px;
    }

    效果:子项高度固定为 100px。

3.3 注意事项

  • 优先级flex-basis 优先级高于 widthheight,但 min-width/max-widthmin-height/max-height 优先级更高。
  • 场景选择 :根据需求选择 flex: none(完全固定)或 flex: 1 1 200px(固定初始尺寸但允许伸缩)。
  • 调试技巧 :使用浏览器的开发者工具检查子项的计算尺寸,确认是否被 flex-basis 覆盖。

4. 实战示例:居中布局与响应式卡片

以下是一个综合示例,展示如何使用 Flex 布局实现居中和响应式卡片,并解决 flex: 1 的尺寸问题。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Flex 布局示例</title>
  <style>
    .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-around;
      align-items: center;
      gap: 20px;
      min-height: 100vh;
      background: #f0f0f0;
    }
    .card {
      flex: 0 0 200px; /* 固定宽度 200px */
      background: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      text-align: center;
      height: 100px; /* 固定高度 */
    }
    .card:nth-child(2) {
      align-self: flex-end;
      order: -1;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="card">卡片 1</div>
    <div class="card">卡片 2</div>
    <div class="card">卡片 3</div>
  </div>
</body>
</html>

效果说明

  • 使用 flex: 0 0 200px 确保卡片宽度固定为 200px,不会被拉伸或压缩。
  • height: 100px 固定卡片高度。
  • flex-flow: row wrap 支持换行,justify-content: space-aroundgap: 20px 确保间距均匀。
  • 第二个卡片通过 align-selforder 调整位置和顺序。

5. 常见问题与解决方案

  1. 为什么子项没有拉伸?
    • 检查 align-items 是否为 stretch,且子项没有固定高度。
  2. 为什么子项不换行?
    • 确保 flex-wrap 设置为 wrapwrap-reverse
  3. 为什么 flex: 1 导致宽度/高度失效?
    • 参考第 3 节,使用 flex-basismin-width/max-width 固定尺寸。
  4. 如何实现完美居中?
    • 使用 justify-content: centeralign-items: center

6. 总结

Flex 布局通过其强大的容器和子项属性,为开发者提供了灵活的布局控制能力。特别需要注意的是,flex: 1 会导致 flex-basis: 0%,从而覆盖显式设置的 widthheight。通过合理设置 flex-basismin-width/max-widthflex: none,可以轻松解决尺寸固定问题。希望这篇教程能帮助你从入门到精通 Flex 布局,快速应用到实际项目中!

点个收藏,关注前端结城,一起用代码点亮前端世界!🚀