Skip to content

Flex 容器属性:掌控 Flexbox 布局的核心

想象你是一个活动策划师,负责安排人们在一个场地里的位置。作为策划师,你需要决定:人们是排成一排还是排成一列?是从左到右还是从右到左排列?如果空间不够,要不要让他们换行?人们之间的间距如何分配?这些决策会影响整个活动的布局和氛围。

在 Flexbox 中,Flex 容器就是这个策划师。它通过一系列属性来控制内部项目的排列方式、对齐方式和空间分配。一旦你掌握了这些属性,就能创造出几乎任何你想要的布局效果。

Display:开启 Flexbox 的钥匙

在深入学习具体的布局属性之前,我们首先要了解如何启用 Flexbox。这就涉及到 display 属性的两个特殊值。

display: flex

这是最常用的方式。当你给一个元素设置 display: flex 时,这个元素本身对外表现为块级元素(独占一行),但它的内部子元素会按照 Flexbox 规则排列。

html
<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>
css
.container {
  display: flex;
  background-color: #f5f5f5;
  padding: 20px;
}

.item {
  padding: 15px 30px;
  background-color: #2196f3;
  color: white;
  margin: 5px;
}

在这个例子中,.container 会独占一行,就像普通的 <div> 一样。但是它内部的三个 .item 元素会水平排列,这是 Flexbox 的效果。

display: inline-flex

有时候,你希望容器本身也能像 inline 元素一样,和其他元素在同一行排列,这时候可以使用 display: inline-flex

html
<div class="page-content">
  这是一段文字,后面跟着一个
  <div class="inline-container">
    <span class="tag">标签1</span>
    <span class="tag">标签2</span>
  </div>
  然后文字继续。
</div>
css
.inline-container {
  display: inline-flex; /* 容器表现为 inline */
  gap: 10px;
  padding: 5px 10px;
  background-color: #e3f2fd;
  border-radius: 4px;
}

.tag {
  padding: 4px 8px;
  background-color: #2196f3;
  color: white;
  border-radius: 3px;
  font-size: 12px;
}

在这个例子中,.inline-container 会融入文本流,就像一个普通的 <span> 元素。但它内部的标签会按照 Flexbox 规则排列。

两者的区别可以这样理解:

  • display: flex:容器对外是 block(独占一行),对内是 flex(子元素遵循 Flexbox)
  • display: inline-flex:容器对外是 inline(可以和其他元素在同一行),对内是 flex

在实际开发中,display: flex 的使用频率远高于 display: inline-flex,因为大多数布局容器都需要独占一行。

Flex-Direction:定义主轴方向

flex-direction 可能是 Flexbox 中最重要的属性之一,因为它决定了主轴的方向,而主轴方向又影响到其他很多属性的行为。

flex-direction: row(默认值)

这是默认值,主轴是水平方向,从左到右。项目会像文字一样从左到右排列。

css
.container {
  display: flex;
  flex-direction: row; /* 可以省略,因为是默认值 */
}
html
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>

项目会按照 1、2、3、4 的顺序从左到右排列。这就是我们最常见的 Flexbox 布局方式。

flex-direction: row-reverse

这个值会反转主轴的方向,让项目从右到左排列。注意,这不仅仅是翻转视觉顺序,而是真正改变了主轴的方向——主轴起点变成了右边,终点变成了左边。

css
.container-reverse {
  display: flex;
  flex-direction: row-reverse;
}

使用相同的 HTML,项目现在会按照 4、3、2、1 的顺序从右到左排列。这在某些布局中很有用,比如你想让最重要的内容放在右边,或者需要适应从右到左书写的语言(如阿拉伯语)。

flex-direction: column

当你需要垂直排列时,使用 column。这会把主轴方向变成垂直的,从上到下。

css
.container-column {
  display: flex;
  flex-direction: column;
  height: 400px; /* 垂直布局通常需要明确高度 */
}

现在项目会按照 1、2、3、4 的顺序从上到下排列,就像正常的块级元素一样。但不同的是,你可以使用 Flexbox 的所有对齐和空间分配功能。

一个常见的应用场景是创建垂直导航菜单:

html
<nav class="sidebar">
  <a href="#" class="nav-link">Dashboard</a>
  <a href="#" class="nav-link">Projects</a>
  <a href="#" class="nav-link">Team</a>
  <a href="#" class="nav-link">Settings</a>
</nav>
css
.sidebar {
  display: flex;
  flex-direction: column;
  width: 200px;
  background-color: #2c3e50;
  padding: 20px 0;
}

.nav-link {
  padding: 15px 25px;
  color: white;
  text-decoration: none;
  transition: background-color 0.3s;
}

.nav-link:hover {
  background-color: #34495e;
}

flex-direction: column-reverse

row-reverse 类似,这个值会反转垂直方向,让项目从下到上排列。

css
.container-column-reverse {
  display: flex;
  flex-direction: column-reverse;
  height: 400px;
}

项目会按照 4、3、2、1 的顺序从下到上排列。这个值在实际中使用较少,但在某些特殊场景下很有用,比如聊天界面中让最新消息显示在底部。

主轴方向的影响

理解 flex-direction 很重要,因为它会影响其他属性的行为:

  • flex-directionrowrow-reverse 时:

    • 主轴是水平方向,justify-content 控制水平对齐
    • 交叉轴是垂直方向,align-items 控制垂直对齐
  • flex-directioncolumncolumn-reverse 时:

    • 主轴是垂直方向,justify-content 控制垂直对齐
    • 交叉轴是水平方向,align-items 控制水平对齐

这看起来可能有点绕,但记住一个简单的规则:justify-content 总是控制主轴方向,align-items 总是控制交叉轴方向。主轴是哪个方向,取决于 flex-direction

Flex-Wrap:控制换行行为

默认情况下,所有 flex 项目都会尝试挤在一行(或一列)里,即使容器空间不够。flex-wrap 属性让你可以改变这个行为。

flex-wrap: nowrap(默认值)

这是默认值,所有项目都会在一行排列,不会换行。如果空间不够,项目会收缩或溢出。

css
.container {
  display: flex;
  flex-wrap: nowrap; /* 默认值,可以省略 */
  width: 500px;
}

.item {
  width: 150px; /* 每个项目 150px */
  padding: 20px;
}

如果我们有 5 个项目,每个 150px,总共需要 750px,但容器只有 500px。在 nowrap 模式下,浏览器会强制让所有项目挤在一行,每个项目会被压缩到 100px 左右。

flex-wrap: wrap

这个值允许项目换行。当一行装不下时,项目会自动换到下一行。

css
.container-wrap {
  display: flex;
  flex-wrap: wrap;
  width: 500px;
}

.item {
  width: 150px;
  padding: 20px;
}

现在,如果有 5 个项目,前 3 个会在第一行(3 × 150px = 450px,小于 500px),后 2 个会自动换到第二行。这就像文字排版一样自然。

一个常见的应用是响应式卡片布局:

html
<div class="card-grid">
  <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 class="card">Card 5</div>
  <div class="card">Card 6</div>
</div>
css
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 20px;
}

.card {
  width: 300px; /* 固定宽度 */
  padding: 30px;
  background-color: white;
  border: 1px solid #ddd;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

在这个布局中,卡片会根据容器宽度自动换行。如果容器宽度是 1000px,一行可以放 3 张卡片(考虑到 gap);如果容器宽度缩小到 700px,一行只能放 2 张卡片。

flex-wrap: wrap-reverse

这个值也允许换行,但新行会出现在上方而不是下方。

css
.container-wrap-reverse {
  display: flex;
  flex-wrap: wrap-reverse;
  width: 500px;
}

如果有 5 个项目需要两行,使用 wrap 时,第 1-3 项在上面,第 4-5 项在下面。使用 wrap-reverse 时,第 4-5 项会在上面,第 1-3 项在下面。

这个值在实际中使用很少,但在某些特殊的视觉设计中可能会用到。

Flex-Flow:Flex-Direction 和 Flex-Wrap 的简写

flex-flowflex-directionflex-wrap 的简写属性,可以让代码更简洁。

css
/* 分开写 */
.container {
  flex-direction: row;
  flex-wrap: wrap;
}

/* 使用简写 */
.container {
  flex-flow: row wrap;
}

第一个值是 flex-direction,第二个值是 flex-wrap。如果只写一个值,另一个会使用默认值。

css
.container {
  flex-flow: column; /* 等同于 flex-direction: column; flex-wrap: nowrap; */
}

在实际开发中,使用 flex-flow 还是分开写 flex-directionflex-wrap,主要看个人偏好和团队规范。简写更简洁,分开写更明确。

Justify-Content:主轴对齐方式

justify-content 控制项目在主轴方向上的对齐和空间分配。这是 Flexbox 最常用的属性之一,可以轻松实现各种对齐效果。

justify-content: flex-start(默认值)

项目从主轴起点开始排列,这是默认行为。

css
.container {
  display: flex;
  justify-content: flex-start; /* 默认值 */
}

如果主轴是水平方向(flex-direction: row),项目会靠左对齐。如果主轴是垂直方向(flex-direction: column),项目会靠上对齐。

justify-content: flex-end

项目从主轴终点开始排列。

css
.container-end {
  display: flex;
  justify-content: flex-end;
}

在水平主轴中,项目会靠右对齐。在垂直主轴中,项目会靠下对齐。

这在创建右对齐的导航栏或按钮组时很有用:

html
<div class="button-group">
  <button class="btn btn-cancel">Cancel</button>
  <button class="btn btn-primary">Save</button>
</div>
css
.button-group {
  display: flex;
  justify-content: flex-end; /* 按钮靠右对齐 */
  gap: 15px;
  padding: 20px;
}

.btn {
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.btn-cancel {
  background-color: #e0e0e0;
  color: #333;
}

.btn-primary {
  background-color: #2196f3;
  color: white;
}

justify-content: center

项目在主轴上居中排列。

css
.container-center {
  display: flex;
  justify-content: center;
}

这是实现水平居中最简单的方法。在传统 CSS 中,水平居中需要设置 margin: 0 auto 并且还要知道元素宽度。在 Flexbox 中,只需要一行 justify-content: center

html
<div class="hero">
  <div class="hero-content">
    <h1>Welcome to TechCorp</h1>
    <p>Innovative solutions for modern businesses</p>
    <button class="cta-button">Get Started</button>
  </div>
</div>
css
.hero {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  min-height: 500px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.hero-content {
  text-align: center;
  color: white;
}

justify-content: space-between

这是一个非常实用的值。它会把项目均匀分布,第一个项目靠起点,最后一个项目靠终点,其他项目平均分布在中间。

css
.container-between {
  display: flex;
  justify-content: space-between;
}

让我们看一个具体的例子。假设容器宽度是 600px,有 4 个项目,每个项目宽度是 100px:

html
<div class="nav">
  <div class="logo">Logo</div>
  <div class="nav-links">
    <a href="#">Home</a>
    <a href="#">Products</a>
    <a href="#">Contact</a>
  </div>
</div>
css
.nav {
  display: flex;
  justify-content: space-between; /* Logo 靠左,链接靠右 */
  align-items: center;
  padding: 20px 40px;
  background-color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.logo {
  font-size: 24px;
  font-weight: bold;
  color: #2196f3;
}

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

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

在这个导航栏中,Logo 会自动靠左,导航链接会自动靠右,中间的空白会自动填充。这是 space-between 最常见的应用场景。

justify-content: space-around

这个值会给每个项目的两侧分配相等的空间。注意,这意味着项目之间的空间是项目与边缘空间的两倍。

css
.container-around {
  display: flex;
  justify-content: space-around;
}

如果容器宽度是 800px,有 3 个项目,每个 100px,剩余空间是 500px。这 500px 会被分成 6 份(每个项目左右各一份),每份约 83px。所以:

  • 左边缘到第一个项目:83px
  • 第一个项目到第二个项目:166px(83px + 83px)
  • 第二个项目到第三个项目:166px
  • 第三个项目到右边缘:83px

justify-content: space-evenly

这个值会让所有空间都相等,包括项目与边缘的空间。

css
.container-evenly {
  display: flex;
  justify-content: space-evenly;
}

使用相同的例子(容器 800px,3 个项目各 100px),剩余的 500px 会被分成 4 份(项目两侧和两个边缘),每份 125px。所以:

  • 左边缘到第一个项目:125px
  • 第一个项目到第二个项目:125px
  • 第二个项目到第三个项目:125px
  • 第三个项目到右边缘:125px

这种均匀分布的效果在图标组、社交媒体链接等场景中很有用:

html
<div class="social-links">
  <a href="#" class="social-icon">📘</a>
  <a href="#" class="social-icon">🐦</a>
  <a href="#" class="social-icon">📷</a>
  <a href="#" class="social-icon">💼</a>
</div>
css
.social-links {
  display: flex;
  justify-content: space-evenly;
  padding: 30px;
  background-color: #f5f5f5;
  border-radius: 8px;
}

.social-icon {
  font-size: 32px;
  text-decoration: none;
  transition: transform 0.3s;
}

.social-icon:hover {
  transform: scale(1.2);
}

Align-Items:交叉轴对齐方式

如果说 justify-content 控制主轴,那么 align-items 就是控制交叉轴的。它决定项目在交叉轴方向上如何对齐。

align-items: stretch(默认值)

这是默认值,项目会拉伸以填充容器在交叉轴方向的高度(或宽度)。

css
.container {
  display: flex;
  align-items: stretch; /* 默认值 */
  height: 200px;
}

如果容器高度是 200px,所有项目都会自动拉伸到 200px 高,即使它们的内容很少。这就是为什么在 Flexbox 中实现等高列如此简单。

需要注意的是,如果项目设置了明确的高度(在主轴为 row 时)或宽度(在主轴为 column 时),stretch 效果会失效。

align-items: flex-start

项目在交叉轴的起点对齐。

css
.container-start {
  display: flex;
  align-items: flex-start;
  height: 200px;
}

在水平主轴中,项目会靠上对齐。在垂直主轴中,项目会靠左对齐。项目不会拉伸,而是保持自己的自然高度。

align-items: flex-end

项目在交叉轴的终点对齐。

css
.container-end {
  display: flex;
  align-items: flex-end;
  height: 200px;
}

在水平主轴中,项目会靠下对齐。这在创建底部对齐的元素时很有用,比如价格卡片中的底部按钮。

align-items: center

项目在交叉轴上居中对齐。这可能是 align-items 中最常用的值之一。

css
.container-center {
  display: flex;
  align-items: center;
  height: 200px;
}

结合 justify-content: center,可以轻松实现完美的水平垂直居中:

css
.perfect-center {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  height: 400px;
  background-color: #f5f5f5;
}

这两行代码解决了 CSS 中最古老的难题之一。

align-items: baseline

项目按照基线对齐。基线是文字排版中的概念,简单理解就是文字底部的参考线。

html
<div class="baseline-demo">
  <div class="item item-small">Small</div>
  <div class="item item-medium">Medium</div>
  <div class="item item-large">Large</div>
</div>
css
.baseline-demo {
  display: flex;
  align-items: baseline;
  height: 200px;
  background-color: #f5f5f5;
}

.item-small {
  font-size: 16px;
}

.item-medium {
  font-size: 24px;
}

.item-large {
  font-size: 48px;
}

尽管三个项目的字体大小不同,它们的文字底部会在同一条线上。这在需要对齐不同大小文字的场景中很有用。

Align-Content:多行对齐

align-content 只在有多行的情况下才有效果,也就是当 flex-wrap: wrap 并且项目确实换行时。它控制多行之间的对齐和空间分配。

为什么需要 align-content

当项目换行后,会产生多个行(或列)。align-items 控制每一行内部项目的对齐,而 align-content 控制这些行本身的对齐。

html
<div class="multi-line">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
css
.multi-line {
  display: flex;
  flex-wrap: wrap;
  width: 400px;
  height: 300px;
  background-color: #f5f5f5;
  border: 2px solid #333;
}

.item {
  width: 120px;
  padding: 20px;
  background-color: #2196f3;
  color: white;
  margin: 5px;
}

在这个例子中,每行可以放 3 个项目(考虑到 margin),所以会有两行。align-content 决定这两行如何在 300px 的高度中分布。

align-content 的各种取值

align-content 的取值和 justify-content 很相似:

  • stretch(默认值):行会拉伸以填充剩余空间
  • flex-start:行靠交叉轴起点
  • flex-end:行靠交叉轴终点
  • center:行在交叉轴上居中
  • space-between:第一行靠起点,最后一行靠终点,其他行均匀分布
  • space-around:每行两侧有相等的空间
  • space-evenly:所有空间都相等
css
/* 行之间均匀分布 */
.multi-line-between {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
  width: 400px;
  height: 300px;
}

Gap:现代的间距控制

gap 是一个相对较新的属性,它提供了一种更直观的方式来设置项目之间的间距。在 gap 出现之前,我们通常用 margin 来设置间距,但这会导致一些问题。

传统方法的问题

使用 margin 设置间距时,边缘的项目也会有 margin,这通常不是我们想要的:

css
/* 使用 margin 的问题 */
.item {
  margin: 10px; /* 每个项目都有 margin */
}

这会导致容器的边缘也有 10px 的空白。我们需要用各种技巧来消除边缘的 margin,比如:

css
.container {
  margin: -10px; /* 用负 margin 抵消 */
}

.item {
  margin: 10px;
}

/* 或者 */
.item:first-child {
  margin-left: 0;
}

.item:last-child {
  margin-right: 0;
}

这些方法都不够优雅。

使用 gap 属性

gap 属性只在项目之间创建间距,不会在边缘创建间距:

css
.container {
  display: flex;
  gap: 20px; /* 只在项目之间创建 20px 的间距 */
}

就这么简单!不需要负 margin,不需要处理边缘情况。

gap 实际上是 row-gapcolumn-gap 的简写:

css
/* 完整写法 */
.container {
  row-gap: 20px; /* 行之间的间距 */
  column-gap: 30px; /* 列之间的间距 */
}

/* 简写 */
.container {
  gap: 20px 30px; /* 第一个值是 row-gap,第二个值是 column-gap */
}

/* 如果两个值相同,可以只写一个 */
.container {
  gap: 20px; /* row-gap 和 column-gap 都是 20px */
}

在换行的 Flexbox 布局中,gap 特别有用:

css
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 30px; /* 卡片之间都有 30px 间距 */
}

.card {
  width: calc(33.333% - 20px); /* 考虑 gap 的宽度计算 */
}

浏览器支持

需要注意的是,gap 属性在 Flexbox 中的支持相对较新。旧版浏览器可能不支持。如果你需要支持旧浏览器,可能还是要使用传统的 margin 方法。

主流浏览器的支持情况(Flexbox 中的 gap):

  • Chrome 84+ (2020 年)
  • Firefox 63+ (2018 年)
  • Safari 14.1+ (2021 年)
  • Edge 84+ (2020 年)

如果你的项目需要支持更旧的浏览器,可以使用 CSS 特性检测:

css
.container {
  display: flex;
}

.item {
  margin: 10px; /* 降级方案 */
}

@supports (gap: 20px) {
  .container {
    gap: 20px;
  }

  .item {
    margin: 0; /* 如果支持 gap,取消 margin */
  }
}

实际应用示例

让我们通过几个完整的例子来综合应用这些属性。

响应式导航栏

html
<nav class="navbar">
  <div class="brand">
    <img src="logo.png" alt="Logo" class="logo" />
    <span class="brand-name">TechCorp</span>
  </div>
  <ul class="nav-menu">
    <li><a href="#home">Home</a></li>
    <li><a href="#services">Services</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
  <div class="nav-actions">
    <button class="btn-login">Login</button>
    <button class="btn-signup">Sign Up</button>
  </div>
</nav>
css
.navbar {
  display: flex;
  justify-content: space-between; /* 三个区域分别在两端和中间 */
  align-items: center; /* 垂直居中 */
  padding: 15px 40px;
  background-color: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo {
  width: 40px;
  height: 40px;
}

.brand-name {
  font-size: 20px;
  font-weight: bold;
  color: #2196f3;
}

.nav-menu {
  display: flex;
  gap: 30px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-menu a {
  color: #333;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.3s;
}

.nav-menu a:hover {
  color: #2196f3;
}

.nav-actions {
  display: flex;
  gap: 15px;
}

.btn-login,
.btn-signup {
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.3s;
}

.btn-login {
  background-color: transparent;
  color: #2196f3;
}

.btn-login:hover {
  background-color: #e3f2fd;
}

.btn-signup {
  background-color: #2196f3;
  color: white;
}

.btn-signup:hover {
  background-color: #1976d2;
}

/* 响应式:小屏幕 */
@media (max-width: 768px) {
  .navbar {
    flex-direction: column;
    gap: 20px;
  }

  .nav-menu {
    flex-direction: column;
    text-align: center;
    gap: 15px;
  }
}

价格表布局

html
<div class="pricing-container">
  <div class="pricing-card">
    <h3>Starter</h3>
    <div class="price">$9<span>/month</span></div>
    <ul class="features">
      <li>5 Projects</li>
      <li>2GB Storage</li>
      <li>Email Support</li>
    </ul>
    <button class="btn-choose">Choose Plan</button>
  </div>
  <div class="pricing-card featured">
    <div class="badge">Popular</div>
    <h3>Professional</h3>
    <div class="price">$29<span>/month</span></div>
    <ul class="features">
      <li>Unlimited Projects</li>
      <li>50GB Storage</li>
      <li>Priority Support</li>
      <li>Advanced Analytics</li>
    </ul>
    <button class="btn-choose">Choose Plan</button>
  </div>
  <div class="pricing-card">
    <h3>Enterprise</h3>
    <div class="price">$99<span>/month</span></div>
    <ul class="features">
      <li>Unlimited Everything</li>
      <li>500GB Storage</li>
      <li>24/7 Support</li>
      <li>Custom Solutions</li>
    </ul>
    <button class="btn-choose">Choose Plan</button>
  </div>
</div>
css
.pricing-container {
  display: flex;
  justify-content: center; /* 卡片居中 */
  align-items: stretch; /* 所有卡片等高 */
  gap: 30px;
  padding: 60px 20px;
  background-color: #f5f5f5;
}

.pricing-card {
  position: relative;
  display: flex;
  flex-direction: column; /* 垂直排列内容 */
  width: 320px;
  padding: 40px 30px;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s, box-shadow 0.3s;
}

.pricing-card:hover {
  transform: translateY(-8px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.pricing-card.featured {
  border: 2px solid #2196f3;
  transform: scale(1.05);
}

.badge {
  position: absolute;
  top: 20px;
  right: 20px;
  padding: 6px 12px;
  background-color: #2196f3;
  color: white;
  font-size: 12px;
  font-weight: bold;
  border-radius: 4px;
}

.pricing-card h3 {
  margin: 0 0 20px 0;
  font-size: 24px;
  color: #333;
}

.price {
  margin-bottom: 30px;
  font-size: 48px;
  font-weight: bold;
  color: #2196f3;
}

.price span {
  font-size: 18px;
  color: #666;
  font-weight: normal;
}

.features {
  flex-grow: 1; /* 占据所有剩余空间 */
  margin: 0 0 30px 0;
  padding: 0;
  list-style: none;
}

.features li {
  padding: 12px 0;
  color: #666;
  border-bottom: 1px solid #eee;
}

.features li:last-child {
  border-bottom: none;
}

.btn-choose {
  padding: 14px 28px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s;
}

.btn-choose:hover {
  background-color: #1976d2;
}

总结

Flex 容器的属性是掌握 Flexbox 布局的核心。让我们回顾一下关键点:

核心属性:

  • display: flex / inline-flex:启用 Flexbox,决定容器的外部表现
  • flex-direction:定义主轴方向(row, column, row-reverse, column-reverse)
  • flex-wrap:控制是否换行(nowrap, wrap, wrap-reverse)
  • justify-content:主轴对齐(flex-start, flex-end, center, space-between, space-around, space-evenly)
  • align-items:交叉轴对齐(stretch, flex-start, flex-end, center, baseline)
  • align-content:多行对齐(只在换行时有效)
  • gap:项目间距(现代方法,简洁直观)

记忆技巧:

  • justify-content 总是控制主轴
  • align-items 总是控制交叉轴
  • 主轴方向由 flex-direction 决定
  • gap 只在项目之间创建间距,不影响边缘

最佳实践:

  1. 从简单的 display: flex 开始
  2. 先确定主轴方向(flex-direction
  3. 根据需要调整对齐方式(justify-contentalign-items
  4. 使用 gap 而不是 margin 来设置间距(如果浏览器支持)
  5. 在需要换行的布局中使用 flex-wrap: wrap

掌握这些容器属性后,你已经可以创建大多数常见的布局了。在下一节中,我们将学习 Flex 项目的属性,它们让你可以更精细地控制单个项目的行为。