Flex 布局(Flexible Box Layout)是 CSS3 引入的一种现代布局模型,它提供了一种更有效的方式来布局、对齐和分配容器中项目的空间,即使它们的大小是未知或动态变化的。

在CSS中,Flex布局(Flexible Box Layout)是一种用于布局的一维模型,它允许子元素在一条线上排列,可以是水平(行)或垂直(列)。Flex布局的主要目的是使子元素的排列、对齐和分布更加灵活和响应式。

一、Flex 布局的基本概念

1.1 主要术语

  • Flex 容器(Flex Container):设置了 display:flex 或 display:inline-flex 的元素。

  • Flex 项目(Flex Item):Flex 容器的直接子元素。

  • 主轴(Main Axis):Flex 项目排列的主要方向,默认是水平方向。

    关于主轴:

    • Flex布局的默认主轴方向是row(水平方向),这与默认的writing-mode: horizontal-tb(水平书写,从上到下)相对应。

    • 在标准的ltr(从左到右)文本方向下,flex-direction: row会让项目从左到右排列。

    • Flex布局的主轴方向并非固定不变,而是会根据当前元素的writing-mode和direction属性进行调整,以适应不同的文本书写习惯和排版需求。

  • 交叉轴(Cross Axis):与主轴垂直的轴,默认是垂直方向。

  • 主轴起点/终点(Main Start/Main End):Flex 项目在主轴上的排列起点和终点。

  • 交叉轴起点/终点(Cross Start/Cross End):Flex 项目在交叉轴上的排列起点和终点。

  • 主轴尺寸(Main Size):Flex 项目在主轴方向上的尺寸。

  • 交叉轴尺寸(Cross Size):Flex 项目在交叉轴方向上的尺寸。

1.2 创建 Flex 容器

.container {
  display: flex; /* 创建块级 Flex 容器 */
  /* 或 */
  display: inline-flex; /* 创建行内 Flex 容器 */
}

二、Flex 容器的主要属性

2.1 flex-direction

定义主轴方向,决定 Flex 项目的排列方向。

属性值

描述

row

默认值,水平从左到右

row-reverse

水平从右到左

column

垂直从上到下

column-reverse

垂直从下到上

示例:

.container {
  flex-direction: row; /* 默认值,水平从左到右 */
  /* 或 */
  flex-direction: row-reverse; /* 水平从右到左 */
  /* 或 */
  flex-direction: column; /* 垂直从上到下 */
  /* 或 */
  flex-direction: column-reverse; /* 垂直从下到上 */
}

2.2 flex-wrap

定义 Flex 项目是否换行。

属性值

描述

nowrap

默认值,不换行,项目会被压缩

wrap

换行,第一行在上方

wrap-reverse

换行,第一行在下方

示例:

.container {
  flex-wrap: nowrap; /* 默认值,不换行,项目会被压缩 */
  /* 或 */
  flex-wrap: wrap; /* 换行,第一行在上方 */
  /* 或 */
  flex-wrap: wrap-reverse; /* 换行,第一行在下方 */
}

2.3  flex-flow

flex-direction 和 flex-wrap 的简写属性。

示例:

.container {
  flex-flow: row wrap; /* 主轴方向为水平,允许换行 */
}

2.4  justify-content

定义 Flex 项目在主轴上的对齐方式。

属性值

描述

flex-start

默认值,从主轴起点对齐

flex-end

从主轴终点对齐

center

居中对齐

space-between

两端对齐,项目之间的间隔相等

space-around

每个项目两侧的间隔相等

space-evenly

项目之间的间隔和项目与容器边缘的间隔相等

示例:

.container {
  justify-content: flex-start; /* 默认值,从主轴起点对齐 */
  /* 或 */
  justify-content: flex-end; /* 从主轴终点对齐 */
  /* 或 */
  justify-content: center; /* 居中对齐 */
  /* 或 */
  justify-content: space-between; /* 两端对齐,项目之间的间隔相等 */
  /* 或 */
  justify-content: space-around; /* 每个项目两侧的间隔相等 */
  /* 或 */
  justify-content: space-evenly; /* 项目之间的间隔和项目与容器边缘的间隔相等 */
}

2.5  align-items

定义 Flex 项目在交叉轴上的对齐方式。

属性值

描述

stretch

默认值,项目被拉伸以填充交叉轴

flex-start

从交叉轴起点对齐

flex-end

从交叉轴终点对齐

center

居中对齐

baseline

项目的基线对齐

示例:

.container {
  align-items: stretch; /* 默认值,项目被拉伸以填充交叉轴 */
  /* 或 */
  align-items: flex-start; /* 从交叉轴起点对齐 */
  /* 或 */
  align-items: flex-end; /* 从交叉轴终点对齐 */
  /* 或 */
  align-items: center; /* 居中对齐 */
  /* 或 */
  align-items: baseline; /* 项目的基线对齐 */
}

2.6 align-content

定义多行 Flex 项目在交叉轴上的对齐方式(当项目换行时生效)。

属性值

描述

stretch

默认值,拉伸以填充交叉轴

flex-start

从交叉轴起点对齐

flex-end

从交叉轴终点对齐

center

居中对齐

space-between

两端对齐,行之间的间隔相等

space-around

每行两侧的间隔相等

.container {
  align-content: stretch; /* 默认值,拉伸以填充交叉轴 */
  /* 或 */
  align-content: flex-start; /* 从交叉轴起点对齐 */
  /* 或 */
  align-content: flex-end; /* 从交叉轴终点对齐 */
  /* 或 */
  align-content: center; /* 居中对齐 */
  /* 或 */
  align-content: space-between; /* 两端对齐,行之间的间隔相等 */
  /* 或 */
  align-content: space-around; /* 每行两侧的间隔相等 */
}

三、Flex 项目的主要属性

3.1  flex-grow

定义项目的放大比例,默认值为 0(即如果有剩余空间,也不放大)。

示例:

.item {
  flex-grow: 1; /* 项目将等分剩余空间 */
}

3.2  flex-shrink

定义项目的缩小比例,默认值为 1(即如果空间不足,项目将缩小)。

示例:

.item {
  flex-shrink: 0; /* 项目不会缩小 */
}

3.3 flex-basis

定义项目在分配多余空间之前的初始大小,默认值为 auto(即项目的原始大小)。

示例:

.item {
  flex-basis: 200px; /* 项目的初始宽度为 200px */
  /* 或 */
  flex-basis: 50%; /* 项目的初始宽度为容器的 50% */
}

3.4 flex

flex-grow、flex-shrink、flex-basis 的简写属性,默认值为 0 1 auto。

示例:

.item {
  flex: 1; /* 相当于 flex: 1 1 0 */
  /* 或 */
  flex: 1 1 auto; /* 放大比例 1,缩小比例 1,初始大小 auto */
}

3.5 align-self

允许单个项目有与其他项目不同的交叉轴对齐方式,覆盖容器的 align-items 属性。

示例:

.item {
  align-self: flex-end; /* 该项目在交叉轴上从终点对齐 */
}

3.6 order

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

示例:

.item {
  order: -1; /* 该项目将排在最前面 */
}

四、Flex 布局的实际应用示例

4.1 实现三列等高布局

.container {
  display: flex;
}
.item {
  flex: 1;
  padding: 1rem;
  border: 1px solid gray;
}

<div class="container">
  <div class="item">列 1</div>
  <div class="item">列 2<br>多行文本<br>测试等高</div>
  <div class="item">列 3</div>
</div>

4.2 实现导航栏布局

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  background-color: #333;
  color: white;
}
.nav-list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-list li {
  margin-left: 20px;
  padding: 20px 0;
}

<nav class="nav">
  <div class="logo">Logo</div>
  <ul class="nav-list">
    <li>首页</li>
    <li>产品</li>
    <li>关于我们</li>
    <li>联系我们</li>
  </ul>
</nav>

4.3 实现卡片布局

.card-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
}
.card {
    flex: 0 0 300px;
    margin: 20px;
    border: 1px solid #ccc;
    border-radius: 5px;
    overflow: hidden;
}
.card img {
    width: 100%;
    height: 200px;
    object-fit: cover;
}
.card h3, .card p {
    padding: 0 15px;
}

<div class="card-container">
    <div class="card">
        <img src="https://placehold.co/600x400" alt="Card 1">
        <h3>Card 1</h3>
        <p>这是卡片 1 的内容</p>
    </div>
    <div class="card">
        <img src="https://placehold.co/600x400" alt="Card 2">
        <h3>Card 2</h3>
        <p>这是卡片 2 的内容</p>
    </div>
    <div class="card">
        <img src="https://placehold.co/600x400" alt="Card 3">
        <h3>Card 3</h3>
        <p>这是卡片 3 的内容</p>
    </div>
</div>

五、Flex 布局的优势

  1. 简单易用:相比传统的布局方式(如浮动、定位),Flex 布局的语法更简洁,更易于理解和使用。

  2. 灵活响应:能够轻松适应不同屏幕尺寸和设备。

  3. 强大的对齐能力:提供了丰富的对齐方式,能够轻松实现各种复杂的布局需求。

  4. 避免了浮动的局限性:不需要清除浮动,避免了布局塌陷等问题。

  5. 支持动态内容:能够很好地处理内容大小变化的情况。

通过学习和掌握 Flex 布局,你可以更高效地实现各种复杂的网页布局,提升开发效率和用户体验。建议结合Cnb项目中的示例文件进行实践,加深对 Flex 布局的理解和应用。