尧图网站设计 尧图网站设计YAOTU DESIGN
TUTORIAL · LAYOUT

页面布局实战

Flex 管一维,Grid 管二维。把两套布局方案搭配好,90% 的页面骨架都能稳稳搭出来。

Flex 与 Grid 布局实战
难度 · 进阶 时长 · 约 18 分钟 更新 · 2026-07-16

Flex 与 Grid 布局实战:一维与二维的取舍

作者 · 尧图设计编辑部 发布 · 2026-07-16 阅读 · 1.8k

浮动和定位的时代过去了,现在做布局主要是 Flex 和 Grid 两套方案。很多人纠结该学哪个,其实它们不是二选一:Flex 适合“一条线”上的排列(一行或一列),Grid 适合“一张网”上的排列(同时管行和列)。理解这个区别,你就知道什么时候用谁。

一、Flex 的主轴与交叉轴

给容器设 display: flex 后,它就变成弹性容器,子元素默认沿“主轴”排成一行。主轴方向由 flex-direction 决定,默认是 row(横向);垂直于主轴的是“交叉轴”。

.row {
  display: flex;
  flex-direction: row;   /* 主轴横向,默认 */
  /* row | row-reverse | column | column-reverse */
}

记住一个核心:justify-content 管主轴方向的对齐,align-items 管交叉轴方向的对齐。方向一变,两个属性管的轴也跟着变,别死记横向纵向。

二、justify-content 与 align-items

.bar {
  display: flex;
  /* 主轴:起点对齐 / 居中 / 末端 / 两端 / 等距 */
  justify-content: space-between;
  /* 交叉轴:拉伸 / 顶部 / 居中 / 底部 */
  align-items: center;
  gap: 16px;            /* 间距,替代写一堆 margin */
}
  • justify-content:flex-start / center / flex-end / space-between / space-around / space-evenly。
  • align-items:stretch(默认)/ flex-start / center / flex-end / baseline。
  • gap:子元素之间的间距,比 margin 干净,不会触发 margin 合并。

场景一:导航栏左右分布

<nav class="nav">
  <a class="nav__logo">Logo</a>
  <div class="nav__links">...</div>
</nav>

.nav {
  display: flex;
  justify-content: space-between;  /* logo 在左,链接在右 */
  align-items: center;             /* 垂直居中 */
  gap: 24px;
}

场景二:任意元素居中

.center {
  display: flex;
  justify-content: center;   /* 主轴居中 */
  align-items: center;       /* 交叉轴居中 */
  min-height: 100vh;
}
提示:用 Flex 做居中,比 position + transform 或 margin:auto 套路都简单,是日常最高频的写法。

三、换行与 flex 简写

默认子元素不换行,多了会被挤压。设 flex-wrap: wrap 后才会换行,配合 gap 形成卡片流。

.card-flow {
  display: flex;
  flex-wrap: wrap;          /* 放不下就换行 */
  gap: 24px;
}
.card-flow > .card {
  flex: 0 1 280px;          /* 不放大 / 可收缩 / 基准宽 280 */
}

flexflex-grow flex-shrink flex-basis 的简写:grow 控制有剩余空间时是否放大,shrink 控制空间不够时是否收缩,basis 是初始尺寸。常用三组:

  • flex: 1:等分剩余空间,常用于自适应主体区。
  • flex: 0 1 280px:固定基准宽、不放大、可收缩,适合卡片流。
  • flex: 0 0 auto:按内容尺寸,不放大不收缩,适合固定按钮。

四、Grid:二维布局的基本盘

当布局需要同时规划行和列,Grid 更顺手。给容器设 display: grid,再用 grid-template-columns 定义列轨道。下面是最常用的等分多列:

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);   /* 三等分 */
  gap: 30px;
}

1fr 是“一份剩余空间”,repeat(3, 1fr) 就是三等分。它和 Flex 卡片流的区别在于:Grid 的列是容器说了算,子元素乖乖对齐成网格;Flex 是子元素按内容流式排,换行后每行对齐不一定整齐。

响应式自适应列数

.auto-grid {
  display: grid;
  /* 每列最小 240px,剩余等分:放得下就多列,放不下自动少列 */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 24px;
}

这一行几乎能解决所有“卡片墙”需求,且天然响应式,不用写媒体查询。

五、Grid 区域命名

Grid 真正强大的地方在于可以用名字画布局图,复杂页面骨架一眼看懂。先用 grid-template-areas 画出结构,再把子元素 assign 到对应区域:

.page {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "side   main"
    "footer footer";
  min-height: 100vh;
}
.page__header { grid-area: header; }
.page__side   { grid-area: side; }
.page__main   { grid-area: main; }
.page__footer { grid-area: footer; }

这种写法可读性极强,改布局时只要调 areas 那几行字符串。响应式时甚至能整块重排:

@media (max-width: 768px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "side"
      "footer";
  }
}
提示:区域命名要求每行的列数一致,重复出现的名字会合并成跨列区域。画图时把名字对齐成方阵,最不容易出错。

六、何时用 Flex,何时用 Grid

给一个简单的判断标准:只关心一个方向的对齐和分布,用 Flex;要同时规划行列、有明确的网格结构,用 Grid。实际项目里常常嵌套使用——外层 Grid 切大区,区内用 Flex 排细节。

  • 导航栏、按钮组、表单一行、单行/单列居中 → Flex。
  • 卡片墙、多栏页面骨架、仪表盘 → Grid。
  • 组件内部小排列用 Flex,页面级骨架用 Grid,是常见搭配。

把这两套方案练熟,再复杂的页面也拆得开。下一课我们让布局在不同屏幕下都好用——进入响应式断点。