BlockCoder
前端开发··14 分钟

CSS Grid 与 Flexbox:现代布局技术对比指南

深入对比 CSS Grid 和 Flexbox 的特性和使用场景,掌握现代 CSS 布局的核心技术,构建响应式和灵活的网页布局。

#CSS#Grid#Flexbox#布局#响应式设计

CSS Grid 和 Flexbox 是现代 CSS 布局的两大核心技术。理解它们的差异和适用场景,能让你构建更灵活、更强大的网页布局。

🤔 Grid vs Flexbox:何时使用?

Flexbox - 一维布局

  • 适用场景:导航栏、按钮组、卡片内容对齐
  • 特点:主轴和交叉轴的一维布局
  • 优势:内容驱动的布局,自动分配空间

CSS Grid - 二维布局

  • 适用场景:页面整体布局、复杂的网格系统
  • 特点:行和列的二维网格系统
  • 优势:精确控制元素位置,复杂布局简单实现

🎯 Flexbox 深入解析

基础概念

css
1.flex-container {
2  display: flex;
3  /* 主轴方向 */
4  flex-direction: row; /* row | row-reverse | column | column-reverse */
5  
6  /* 主轴对齐 */
7  justify-content: flex-start; /* flex-start | flex-end | center | space-between | space-around | space-evenly */
8  
9  /* 交叉轴对齐 */
10  align-items: stretch; /* stretch | flex-start | flex-end | center | baseline */
11  
12  /* 换行 */
13  flex-wrap: nowrap; /* nowrap | wrap | wrap-reverse */
14}

实用布局示例

1. 居中布局

css
1.center-container {
2  display: flex;
3  justify-content: center;
4  align-items: center;
5  height: 100vh;
6}

2. 导航栏布局

css
1.navbar {
2  display: flex;
3  justify-content: space-between;
4  align-items: center;
5  padding: 1rem 2rem;
6}
7
8.nav-logo {
9  flex-shrink: 0;
10}
11
12.nav-menu {
13  display: flex;
14  gap: 2rem;
15  list-style: none;
16}
17
18.nav-actions {
19  display: flex;
20  gap: 1rem;
21}

3. 卡片布局

css
1.card {
2  display: flex;
3  flex-direction: column;
4  height: 100%;
5}
6
7.card-content {
8  flex: 1; /* 占据剩余空间 */
9  padding: 1rem;
10}
11
12.card-actions {
13  padding: 1rem;
14  border-top: 1px solid #eee;
15}

4. 响应式网格

css
1.flex-grid {
2  display: flex;
3  flex-wrap: wrap;
4  gap: 1rem;
5}
6
7.flex-grid-item {
8  flex: 1 1 300px; /* grow shrink basis */
9  min-width: 0; /* 防止内容溢出 */
10}

🏗️ CSS Grid 详解

基础概念

css
1.grid-container {
2  display: grid;
3  
4  /* 定义列 */
5  grid-template-columns: 1fr 2fr 1fr; /* 或 repeat(3, 1fr) */
6  
7  /* 定义行 */
8  grid-template-rows: auto 1fr auto;
9  
10  /* 间距 */
11  gap: 1rem; /* 或 row-gap, column-gap */
12  
13  /* 对齐 */
14  justify-items: stretch; /* start | end | center | stretch */
15  align-items: stretch; /* start | end | center | stretch */
16}

复杂布局示例

1. 经典网页布局

css
1.page-layout {
2  display: grid;
3  grid-template-areas:
4    "header header header"
5    "sidebar main aside"
6    "footer footer footer";
7  grid-template-columns: 200px 1fr 200px;
8  grid-template-rows: auto 1fr auto;
9  min-height: 100vh;
10}
11
12.header { grid-area: header; }
13.sidebar { grid-area: sidebar; }
14.main { grid-area: main; }
15.aside { grid-area: aside; }
16.footer { grid-area: footer; }

2. 响应式图片网格

css
1.image-grid {
2  display: grid;
3  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
4  gap: 1rem;
5}
6
7.image-item {
8  aspect-ratio: 1;
9  overflow: hidden;
10  border-radius: 8px;
11}
12
13.image-item img {
14  width: 100%;
15  height: 100%;
16  object-fit: cover;
17}

3. 复杂卡片布局

css
1.dashboard {
2  display: grid;
3  grid-template-columns: repeat(12, 1fr);
4  gap: 1rem;
5  padding: 1rem;
6}
7
8.widget-large {
9  grid-column: span 8;
10  grid-row: span 2;
11}
12
13.widget-medium {
14  grid-column: span 4;
15}
16
17.widget-small {
18  grid-column: span 3;
19}
20
21/* 响应式调整 */
22@media (max-width: 768px) {
23  .dashboard {
24    grid-template-columns: 1fr;
25  }
26  
27  .widget-large,
28  .widget-medium,
29  .widget-small {
30    grid-column: 1;
31  }
32}

🎨 实战案例:博客布局

HTML 结构

html
1<div class="blog-layout">
2  <header class="blog-header">
3    <nav class="navbar">
4      <div class="nav-brand">JieCheng.Dev</div>
5      <ul class="nav-menu">
6        <li><a href="/">首页</a></li>
7        <li><a href="/posts">文章</a></li>
8        <li><a href="/about">关于</a></li>
9      </ul>
10    </nav>
11  </header>
12  
13  <main class="blog-main">
14    <section class="content">
15      <article class="post-card">
16        <h2>文章标题</h2>
17        <p>文章摘要...</p>
18        <div class="post-meta">
19          <span>作者</span>
20          <span>日期</span>
21        </div>
22      </article>
23    </section>
24    
25    <aside class="sidebar">
26      <div class="widget">
27        <h3>最新文章</h3>
28        <ul>...</ul>
29      </div>
30    </aside>
31  </main>
32  
33  <footer class="blog-footer">
34    <p>&copy; 2024 JieCheng.Dev</p>
35  </footer>
36</div>

CSS 实现

css
1/* Grid 布局 - 整体结构 */
2.blog-layout {
3  display: grid;
4  grid-template-areas:
5    "header"
6    "main"
7    "footer";
8  grid-template-rows: auto 1fr auto;
9  min-height: 100vh;
10}
11
12.blog-header { grid-area: header; }
13.blog-main { grid-area: main; }
14.blog-footer { grid-area: footer; }
15
16/* Flexbox 布局 - 导航栏 */
17.navbar {
18  display: flex;
19  justify-content: space-between;
20  align-items: center;
21  padding: 1rem 2rem;
22  background: white;
23  border-bottom: 1px solid #eee;
24}
25
26.nav-menu {
27  display: flex;
28  gap: 2rem;
29  list-style: none;
30  margin: 0;
31  padding: 0;
32}
33
34/* Grid 布局 - 主要内容区 */
35.blog-main {
36  display: grid;
37  grid-template-columns: 1fr 300px;
38  gap: 2rem;
39  padding: 2rem;
40  max-width: 1200px;
41  margin: 0 auto;
42}
43
44/* Flexbox 布局 - 文章卡片 */
45.post-card {
46  display: flex;
47  flex-direction: column;
48  background: white;
49  border-radius: 8px;
50  padding: 1.5rem;
51  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
52  margin-bottom: 2rem;
53}
54
55.post-meta {
56  display: flex;
57  gap: 1rem;
58  margin-top: auto;
59  padding-top: 1rem;
60  border-top: 1px solid #eee;
61  color: #666;
62  font-size: 0.9rem;
63}
64
65/* 响应式设计 */
66@media (max-width: 768px) {
67  .blog-main {
68    grid-template-columns: 1fr;
69  }
70  
71  .navbar {
72    flex-direction: column;
73    gap: 1rem;
74  }
75  
76  .nav-menu {
77    gap: 1rem;
78  }
79}

🚀 高级技巧

1. 子网格 (Subgrid)

css
1.card-grid {
2  display: grid;
3  grid-template-columns: repeat(3, 1fr);
4  gap: 1rem;
5}
6
7.card {
8  display: grid;
9  grid-template-rows: subgrid;
10  grid-row: span 3;
11}

2. 容器查询

css
1.card-container {
2  container-type: inline-size;
3}
4
5@container (min-width: 400px) {
6  .card {
7    grid-template-columns: 1fr 2fr;
8  }
9}

3. Grid + Flexbox 组合

css
1.hybrid-layout {
2  display: grid;
3  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4  gap: 1rem;
5}
6
7.hybrid-item {
8  display: flex;
9  flex-direction: column;
10}
11
12.hybrid-content {
13  flex: 1;
14}

📊 性能考虑

1. 避免不必要的重排

css
1/* ✅ 使用 transform 而不是改变 grid 属性 */
2.item {
3  transform: translateX(100px);
4}
5
6/* ❌ 避免频繁改变 grid-column */
7.item {
8  grid-column: 2;
9}

2. 合理使用 auto-fit 和 auto-fill

css
1/* auto-fit: 列会拉伸填满容器 */
2grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
3
4/* auto-fill: 会创建空列 */
5grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

🎯 总结

选择指南:

场景推荐技术原因
导航栏Flexbox一维布局,内容驱动
页面整体布局Grid二维布局,精确控制
卡片内容对齐Flexbox灵活的空间分配
图片网格Grid整齐的网格结构
按钮组Flexbox自动间距分配

关键要点:

  • Grid 用于二维布局,Flexbox 用于一维布局
  • 可以组合使用,发挥各自优势
  • 响应式设计中都有重要作用
  • 现代浏览器支持良好

掌握这两种布局技术,你就能应对绝大多数的网页布局需求!

评论讨论

使用 GitHub 账号登录即可参与讨论