CSS Grid vs Flexbox:2026年Web布局完全指南

CSS Grid vs Flexbox:2026年Web布局完全指南

CSS Grid和Flexbox如何选择?通过实战代码示例了解区别、用途和组合技巧。

2026年3月17日4分钟阅读

CSS布局的演进

CSS布局经历了漫长的演进:从最初的floatposition,到display: table,再到如今的Flexbox和Grid。2026年,这两种现代布局系统已经得到所有主流浏览器的完全支持,成为前端开发的基石。

但很多开发者对这两个工具感到困惑:什么时候用Flexbox?什么时候用Grid?能不能混用?本文将清晰回答这些问题,并提供大量实战代码示例。

核心区别:一维 vs 二维

理解两者最关键的一点:

  • Flexbox(弹性布局):一维布局工具,沿单一轴(横轴或纵轴)排列元素
  • CSS Grid(网格布局):二维布局工具,同时控制行和列
维度FlexboxCSS Grid
布局维度一维(行或列)二维(行和列)
设计方向内容驱动(从内向外)布局驱动(从外向内)
对齐控制强大的轴对齐精确的行列定位
响应式自然弹性精确控制
浏览器支持极佳极佳
学习难度相对简单稍复杂

Flexbox:掌握弹性布局

基础概念

.container {
  display: flex;
  flex-direction: row;         /* 主轴方向:row | row-reverse | column | column-reverse */
  flex-wrap: wrap;             /* 换行:nowrap | wrap | wrap-reverse */
  justify-content: space-between; /* 主轴对齐 */
  align-items: center;         /* 交叉轴对齐 */
  gap: 16px;                   /* 间距 */
}

实战示例1:导航栏

<nav class="navbar">
  <div class="logo">ToolBox Hub</div>
  <ul class="nav-links">
    <li><a href="#">首页</a></li>
    <li><a href="#">工具</a></li>
    <li><a href="#">博客</a></li>
  </ul>
  <button class="cta-btn">开始使用</button>
</nav>
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  height: 64px;
  background: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

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

/* 响应式:移动端隐藏链接 */
@media (max-width: 768px) {
  .nav-links {
    display: none;
  }
}

实战示例2:卡片组件

.card {
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  overflow: hidden;
}

.card-body {
  display: flex;
  flex-direction: column;
  flex: 1;         /* 占据剩余空间 */
  padding: 16px;
}

.card-title {
  font-size: 1.125rem;
  font-weight: 600;
  margin-bottom: 8px;
}

.card-description {
  flex: 1;         /* 推动按钮到底部 */
  color: #6b7280;
  margin-bottom: 16px;
}

.card-action {
  margin-top: auto;  /* 始终在底部 */
}

Flexbox子元素属性

.flex-item {
  flex-grow: 1;    /* 增长比例,默认0 */
  flex-shrink: 1;  /* 收缩比例,默认1 */
  flex-basis: auto; /* 初始大小 */

  /* 简写 */
  flex: 1;         /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
  flex: 0 0 200px; /* 固定宽度200px,不增长不收缩 */

  align-self: flex-start; /* 覆盖容器的align-items */
  order: 2;        /* 排序(默认0) */
}

CSS Grid:掌握网格布局

基础概念

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* 3列等宽 */
  grid-template-rows: auto;               /* 行高自动 */
  gap: 24px;                              /* 行列间距 */
}

实战示例1:经典博客布局

<div class="blog-layout">
  <header class="site-header">网站头部</header>
  <aside class="sidebar">侧边栏</aside>
  <main class="main-content">主内容区</main>
  <footer class="site-footer">页脚</footer>
</div>
.blog-layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 260px 1fr;
  grid-template-rows: 64px 1fr 80px;
  min-height: 100vh;
  gap: 0;
}

.site-header { grid-area: header; background: #1f2937; color: white; }
.sidebar     { grid-area: sidebar; background: #f9fafb; border-right: 1px solid #e5e7eb; }
.main-content { grid-area: main; padding: 24px; }
.site-footer { grid-area: footer; background: #374151; color: white; }

/* 响应式:移动端单列 */
@media (max-width: 768px) {
  .blog-layout {
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
    grid-template-columns: 1fr;
  }
}

实战示例2:响应式图片画廊

.gallery {
  display: grid;
  /* 自动填充列,每列最小200px,最大1fr */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.gallery-item {
  aspect-ratio: 1;  /* 正方形 */
  border-radius: 8px;
  overflow: hidden;
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s;
}

.gallery-item:hover img {
  transform: scale(1.05);
}

/* 特定卡片占据2列 */
.gallery-item.featured {
  grid-column: span 2;
  grid-row: span 2;
}

实战示例3:仪表板布局

.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, auto);
  gap: 20px;
  padding: 24px;
}

/* 统计卡片:4个并排 */
.stat-card {
  /* 默认占1列 */
}

/* 主图表:占2列2行 */
.main-chart {
  grid-column: span 2;
  grid-row: span 2;
}

/* 次要图表:占1列2行 */
.secondary-chart {
  grid-row: span 2;
}

/* 数据表格:占满底部 */
.data-table {
  grid-column: 1 / -1;  /* 从第1列到最后一列 */
}

组合使用:Flexbox + Grid

最强大的布局方式往往是两者的结合:

/* 外层用Grid定义页面布局 */
.page {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* 内层用Flexbox处理组件内布局 */
.card-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.card {
  flex: 1 1 280px;  /* 弹性宽度,最小280px */
  display: flex;
  flex-direction: column;
}

决策指南

使用Flexbox的情况

  • 导航栏(水平排列链接)
  • 按钮组和操作区域
  • 垂直/水平居中单个元素
  • 卡片内部布局(垂直方向)
  • 标签(Chip)列表
  • 表单元素对齐

使用Grid的情况

  • 整体页面布局(Header/Sidebar/Main/Footer)
  • 卡片网格(产品列表、图片画廊)
  • 仪表板布局
  • 需要精确对齐行和列的场景
  • 复杂的杂志风格布局
  • 响应式网格

常见布局解决方案

完美居中

/* Flexbox居中 */
.center-flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Grid居中 */
.center-grid {
  display: grid;
  place-items: center;  /* 等同于 align-items + justify-items */
}

等高卡片

/* 不管内容多少,卡片高度一致 */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  align-items: stretch;  /* 默认值,拉伸到相同高度 */
}

Holy Grail布局(圣杯布局)

.holy-grail {
  display: grid;
  grid-template:
    "header" auto
    "nav main aside" 1fr
    "footer" auto
    / 200px 1fr 200px;
  min-height: 100vh;
}

总结

Flexbox和Grid不是竞争关系,而是互补关系:

  • Flexbox擅长:一维排列、内容驱动的弹性布局、对齐单行或单列元素
  • Grid擅长:二维布局、从外向内的结构定义、复杂的页面级布局

实际开发中,最佳实践是在外层使用Grid定义整体结构,在组件内部使用Flexbox处理细节对齐。熟练掌握这两个工具,你就能优雅地实现任何Web布局,告别float: left和负边距的时代。

相关文章