Skip to content

Flex 布局详解

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

一、基本概念

1. 容器与项目

  • 容器(Container):设置了 display: flexdisplay: inline-flex 的元素
  • 项目(Item):容器的直接子元素

2. 主轴与交叉轴

  • 主轴(Main Axis):默认是水平方向,从左到右
  • 交叉轴(Cross Axis):默认是垂直方向,从上到下

二、容器属性

1. display

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

2. flex-direction

定义主轴方向

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

3. flex-wrap

定义项目是否换行

css
.container {
  flex-wrap: nowrap; /* 默认,不换行 */
  /* 或 */
  flex-wrap: wrap; /* 换行,第一行在上方 */
  /* 或 */
  flex-wrap: wrap-reverse; /* 换行,第一行在下方 */
}

4. flex-flow

flex-directionflex-wrap 的简写

css
.container {
  flex-flow: <flex-direction> <flex-wrap>;
  /* 例如 */
  flex-flow: row wrap;
}

5. justify-content

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

css
.container {
  justify-content: flex-start; /* 默认,左对齐 */
  /* 或 */
  justify-content: flex-end; /* 右对齐 */
  /* 或 */
  justify-content: center; /* 居中 */
  /* 或 */
  justify-content: space-between; /* 两端对齐,项目之间间隔相等 */
  /* 或 */
  justify-content: space-around; /* 项目两侧间隔相等 */
  /* 或 */
  justify-content: space-evenly; /* 所有间隔相等 */
}

6. align-items

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

css
.container {
  align-items: stretch; /* 默认,拉伸填充 */
  /* 或 */
  align-items: flex-start; /* 顶部对齐 */
  /* 或 */
  align-items: flex-end; /* 底部对齐 */
  /* 或 */
  align-items: center; /* 居中对齐 */
  /* 或 */
  align-items: baseline; /* 基线对齐 */
}

7. align-content

定义多根轴线的对齐方式(只有当项目换行时才有效果)

css
.container {
  align-content: stretch; /* 默认,拉伸填充 */
  /* 或 */
  align-content: flex-start; /* 顶部对齐 */
  /* 或 */
  align-content: flex-end; /* 底部对齐 */
  /* 或 */
  align-content: center; /* 居中对齐 */
  /* 或 */
  align-content: space-between; /* 两端对齐 */
  /* 或 */
  align-content: space-around; /* 均匀分布 */
}

三、项目属性

1. order

定义项目的排列顺序,数值越小,排列越靠前

css
.item {
  order: 0; /* 默认值 */
  /* 例如 */
  order: -1; /* 排在前面 */
  order: 1; /* 排在后面 */
}

2. flex-grow

定义项目的放大比例,默认为 0,即不放大

css
.item {
  flex-grow: 0; /* 默认值 */
  /* 例如 */
  flex-grow: 1; /* 等分剩余空间 */
  flex-grow: 2; /* 占据其他项目的 2 倍空间 */
}

3. flex-shrink

定义项目的缩小比例,默认为 1,即空间不足时会缩小

css
.item {
  flex-shrink: 1; /* 默认值 */
  /* 例如 */
  flex-shrink: 0; /* 不缩小 */
  flex-shrink: 2; /* 缩小比例为 2 */
}

4. flex-basis

定义项目在主轴上的初始大小

css
.item {
  flex-basis: auto; /* 默认值,根据内容决定 */
  /* 例如 */
  flex-basis: 100px; /* 固定宽度 */
  flex-basis: 50%; /* 占容器宽度的 50% */
}

5. flex

flex-growflex-shrinkflex-basis 的简写

css
.item {
  flex: 0 1 auto; /* 默认值 */
  /* 或 */
  flex: 1; /* 等同于 flex: 1 1 0% */
  /* 或 */
  flex: none; /* 等同于 flex: 0 0 auto */
  /* 或 */
  flex: auto; /* 等同于 flex: 1 1 auto */
}

6. align-self

定义单个项目在交叉轴上的对齐方式,覆盖容器的 align-items 属性

css
.item {
  align-self: auto; /* 默认值,继承容器的 align-items */
  /* 或 */
  align-self: flex-start; /* 顶部对齐 */
  /* 或 */
  align-self: flex-end; /* 底部对齐 */
  /* 或 */
  align-self: center; /* 居中对齐 */
  /* 或 */
  align-self: baseline; /* 基线对齐 */
  /* 或 */
  align-self: stretch; /* 拉伸填充 */
}

四、常见使用场景

1. 水平居中

css
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

2. 垂直居中

css
.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

3. 导航栏布局

css
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

.logo {
  /* 左侧 logo */
}

.nav-links {
  display: flex;
  gap: 20px;
}

4. 卡片网格布局

css
.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: space-between;
}

.card {
  flex: 1 1 300px; /* 最小宽度 300px,自动填充 */
  /* 其他样式 */
}

5. 响应式布局

css
.container {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }

  .sidebar {
    flex: 0 0 200px;
  }

  .content {
    flex: 1;
  }
}

五、常见问题及解决方案

1. 子元素不换行

问题:设置了 flex-wrap: wrap 但项目仍然不换行 解决方案:检查项目是否设置了固定宽度,或者容器是否有足够的空间

2. 项目大小不一致

问题:使用 flex-grow 时项目大小不一致 解决方案:确保项目的 flex-basis 相同,或者使用 flex: 1 让所有项目等分空间

3. 浏览器兼容性问题

问题:在旧版浏览器中 flex 布局不生效 解决方案:添加浏览器前缀

css
.container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
}

4. 子元素溢出

问题:子元素内容过多导致溢出容器 解决方案:可以设置 overflow: hidden 或者使用 text-overflow: ellipsis 处理文本溢出

5. 垂直居中问题

问题:在某些情况下 align-items: center 不生效 解决方案:确保容器有明确的高度,或者使用 min-height

六、浏览器兼容性

浏览器支持版本
Chrome29+
Firefox28+
Safari9+
Edge12+
IE11+ (部分支持)

七、实例代码

示例 1:基本布局

html
<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

<style>
  .container {
    display: flex;
    justify-content: space-around;
    align-items: center;
    height: 200px;
    background-color: #f0f0f0;
  }

  .item {
    background-color: #3498db;
    color: white;
    padding: 20px;
    border-radius: 5px;
  }
</style>

示例 2:响应式导航栏

html
<nav class="navbar">
  <div class="logo">Logo</div>
  <div class="nav-links">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
  </div>
</nav>

<style>
  .navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 20px;
    background-color: #333;
    color: white;
  }

  .nav-links {
    display: flex;
    gap: 20px;
  }

  .nav-links a {
    color: white;
    text-decoration: none;
  }

  @media (max-width: 768px) {
    .navbar {
      flex-direction: column;
      align-items: flex-start;
    }

    .nav-links {
      margin-top: 10px;
    }
  }
</style>

示例 3:卡片网格

html
<div class="card-container">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
  <div class="card">Card 4</div>
</div>

<style>
  .card-container {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    padding: 20px;
  }

  .card {
    flex: 1 1 200px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    padding: 20px;
    border-radius: 5px;
    text-align: center;
  }
</style>

八、总结

Flex 布局是一种强大的布局工具,它提供了灵活的方式来控制容器内项目的排列、对齐和空间分配。通过合理使用容器属性和项目属性,可以轻松实现各种复杂的布局效果,特别是在响应式设计中表现出色。

掌握 Flex 布局的关键在于理解主轴和交叉轴的概念,以及各种属性的作用和相互关系。通过实践和练习,你可以熟练运用 Flex 布局来创建美观、高效的网页布局。

基于 VitePress 的本地知识库