布局之道——Flex 与 Grid 的协奏

目录

第 1 节 概述

页面结构就像房子的框架——框架不牢,装修再好也没用。

CSS 布局的两大工具是 FlexboxGrid。简单区分:

  • Flex:一维布局,要么横着排,要么竖着排
  • Grid:二维布局,行和列同时控制

Tailwind 把这两者的核心功能包装成了简洁的工具类。

第 2 节 Display 基础

在用 Flex 和 Grid 之前,先了解最基础的 display 类型:

1
2
3
4
<div class="block">块级元素,独占一行</div>
<span class="inline">行内元素,不换行</span>
<span class="inline-block">行内块,不换行但可以设宽高</span>
<div class="hidden">完全隐藏,不占空间</div>
类名行为
block独占一行,可以设宽高
inline行内排列,不能设宽高
inline-block行内排列,可以设宽高
hiddendisplay: none

第 3 节 Flex 布局

3.1 容器

给父元素加上 flex,子元素就自动横向排列:

1
2
3
4
5
<div class="flex">
  <div>项目 1</div>
  <div>项目 2</div>
  <div>项目 3</div>
</div>

3.2 方向

1
2
3
4
<div class="flex flex-row">横向排列(默认)</div>
<div class="flex flex-col">纵向排列</div>
<div class="flex flex-row-reverse">横向反向排列</div>
<div class="flex flex-col-reverse">纵向反向排列</div>

3.3 换行

1
2
3
4
5
6
<div class="flex flex-wrap">
  <!-- 子元素过多时自动换行 -->
</div>
<div class="flex flex-nowrap">
  <!-- 不换行,压缩子元素宽度 -->
</div>

3.4 子元素伸缩

Flex 最强大的能力是子元素可以按比例分配空间:

1
2
3
4
5
<div class="flex">
  <div class="flex-1 bg-blue-500">flex-1 占 1 份</div>
  <div class="flex-1 bg-green-500">flex-1 也占 1 份</div>
  <div class="flex-1 bg-yellow-500">flex-1 也占 1 份</div>
</div>

三个元素宽度相等,各占三分之一。如果把其中一个改成 flex-[2],它就占 2 份空间:

1
2
3
4
5
<div class="flex">
  <div class="flex-1 bg-blue-500">1 份</div>
  <div class="flex-[2] bg-green-500">2 份(两倍宽)</div>
  <div class="flex-1 bg-yellow-500">1 份</div>
</div>
类名等比例初始宽度适用场景
flex-1按比例扩展0等分空间
flex-auto按内容扩展内容宽度内容长度不统一时
flex-initial不自动扩展内容宽度保持固有大小
grow可扩展允许元素填满剩余空间
shrink-0不收缩防止元素被压缩

3.5 主轴对齐(justify)

控制 Flex 容器内元素在主轴方向上的排列:

1
2
3
4
5
6
<div class="flex justify-start">起点对齐(默认)</div>
<div class="flex justify-center">居中对齐</div>
<div class="flex justify-end">末端对齐</div>
<div class="flex justify-between">两端对齐,中间均匀分布</div>
<div class="flex justify-around">每个元素两侧间距相等</div>
<div class="flex justify-evenly">所有间距完全相等</div>

justify-between 是最常用的——它让第一个元素在起点,最后一个在终点,中间的均匀分布。

images/04-flex-justify.svg

3.6 交叉轴对齐(items)

控制 Flex 容器内元素在交叉轴方向上的对齐:

1
2
3
4
<div class="flex items-start">顶部对齐</div>
<div class="flex items-center">垂直居中 —— 最常用</div>
<div class="flex items-end">底部对齐</div>
<div class="flex items-stretch">拉伸填满(默认值)</div>

items-center 搭配 flex 是最常见的组合之一,快速实现垂直居中:

1
2
3
4
<div class="flex items-center gap-4">
  <img class="w-10 h-10 rounded-full" src="avatar.jpg" alt="头像" />
  <span class="font-medium">用户名</span>
</div>

3.7 单个元素对齐(self)

只调整 Flex 中某一个子元素的对齐:

1
2
3
4
5
<div class="flex items-center h-32 bg-gray-100">
  <div class="self-start bg-blue-500">顶部</div>
  <div class="self-center bg-green-500">居中</div>
  <div class="self-end bg-yellow-500">底部</div>
</div>

第 4 节 Grid 布局

Grid 适合做二维排列,比如卡片网格、仪表盘。

4.1 基本用法

1
2
3
4
5
6
7
8
<div class="grid grid-cols-3 gap-6">
  <div class="bg-gray-100 p-4 rounded-lg">卡片 1</div>
  <div class="bg-gray-100 p-4 rounded-lg">卡片 2</div>
  <div class="bg-gray-100 p-4 rounded-lg">卡片 3</div>
  <div class="bg-gray-100 p-4 rounded-lg">卡片 4</div>
  <div class="bg-gray-100 p-4 rounded-lg">卡片 5</div>
  <div class="bg-gray-100 p-4 rounded-lg">卡片 6</div>
</div>

grid-cols-3 将容器分为 3 列,子元素自动按行排列。gap-6 控制行列间距。

images/04-grid-cols.svg

类名列数
grid-cols-1 ~ grid-cols-121~12 列
grid-cols-none不指定列宽

4.2 跨列和跨行

让某个元素占据多列或多行:

1
2
3
4
5
6
<div class="grid grid-cols-3 gap-4">
  <div class="bg-blue-500 p-4 col-span-2">跨 2 列</div>
  <div class="bg-green-500 p-4">普通</div>
  <div class="bg-yellow-500 p-4">普通</div>
  <div class="bg-purple-500 p-4 col-span-3">跨 3 列(整行)</div>
</div>
类名效果
col-span-2跨越 2 列
col-span-full跨越所有列
col-start-1从第 1 列开始
col-end-4到第 4 列结束

行方向同理:row-span-2row-span-fullrow-start-1

4.3 密集排列

一般来说 Grid 按顺序从左到右排列。但可以启用"密集模式"来填充空隙:

1
2
3
<div class="grid grid-cols-3 gap-4 grid-flow-dense">
  <!-- 元素会自动填充空白区域 -->
</div>

第 5 节 定位

除了 Flex 和 Grid,Tailwind 也支持 CSS 定位方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div class="relative">
  <!-- 相对定位,保留占位,做绝对定位的参照 -->
  <div class="absolute top-0 right-0">
    <!-- 绝对定位,相对于最近的 relative 父元素 -->
  </div>
</div>

<div class="fixed top-0 inset-x-0 z-50">
  <!-- 固定定位,相对于浏览器窗口,不随页面滚动 -->
</div>

<div class="sticky top-0">
  <!-- 粘性定位,滚动到顶部后固定 -->
</div>

inset-x-0 表示 left: 0; right: 0;inset-0 表示所有方向都为 0。

技巧

fixed 适合导航栏和浮层,sticky 适合侧边栏和表格表头,absolute 适合下拉菜单和角标。

第 6 节 实战:给产品页搭骨架

现在用布局工具重新组织产品展示页的结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>星光科技 · 智能灯</title>
  <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
</head>
<body>
  <!-- 固定导航栏 -->
  <nav class="fixed top-0 inset-x-0 bg-white/80 backdrop-blur-sm border-b border-gray-100 z-50">
    <div class="max-w-5xl mx-auto flex items-center justify-between px-6 h-16">
      <span class="text-xl font-bold text-gray-900">星光科技</span>
      <div class="flex gap-8 text-gray-600">
        <a href="#" class="hover:text-gray-900">产品</a>
        <a href="#" class="hover:text-gray-900">特性</a>
        <a href="#" class="hover:text-gray-900">用户评价</a>
        <a href="#" class="hover:text-gray-900">联系我们</a>
      </div>
    </div>
  </nav>

  <!-- Hero 区域(留出导航栏高度) -->
  <main class="max-w-5xl mx-auto px-6 pt-32 pb-16">
    <div class="flex flex-col items-center text-center">
      <h1 class="text-5xl font-extrabold text-gray-900">
        智能台灯 <span class="text-blue-600">Lumina</span>
      </h1>
      <p class="mt-6 text-xl text-gray-500 leading-relaxed max-w-2xl">
        光线随你而变。一盏懂你的台灯。
      </p>
      <button class="mt-8 px-8 py-4 bg-blue-600 text-white text-lg font-semibold rounded-xl hover:bg-blue-700">
        立即购买
      </button>
    </div>

    <!-- 特性卡片网格 -->
    <section class="mt-32">
      <h2 class="text-3xl font-bold text-gray-900 text-center">为什么选择 Lumina</h2>
      <div class="mt-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
        <div class="p-6 bg-gray-50 rounded-2xl text-center">
          <div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center mx-auto">
            <span class="text-2xl">🧠</span>
          </div>
          <h3 class="mt-4 text-xl font-semibold text-gray-900">AI 调光</h3>
          <p class="mt-2 text-gray-500 leading-relaxed">
            内置传感器实时感知环境光线,自动调整亮度和色温。
          </p>
        </div>

        <div class="p-6 bg-gray-50 rounded-2xl text-center">
          <div class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center mx-auto">
            <span class="text-2xl">👁️</span>
          </div>
          <h3 class="mt-4 text-xl font-semibold text-gray-900">护眼模式</h3>
          <p class="mt-2 text-gray-500 leading-relaxed">
            无频闪、低蓝光,通过德国莱茵 TÜV 护眼认证。
          </p>
        </div>

        <div class="p-6 bg-gray-50 rounded-2xl text-center">
          <div class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center mx-auto">
            <span class="text-2xl">🎤</span>
          </div>
          <h3 class="mt-4 text-xl font-semibold text-gray-900">语音控制</h3>
          <p class="mt-2 text-gray-500 leading-relaxed">
            支持 Siri、小爱同学、Google Assistant 语音指令。
          </p>
        </div>
      </div>
    </section>

    <!-- 页脚 -->
    <footer class="mt-32 pt-8 border-t border-gray-100 flex items-center justify-between text-sm text-gray-400">
      <span>&copy; 2026 星光科技</span>
      <div class="flex gap-6">
        <a href="#" class="hover:text-gray-600">隐私政策</a>
        <a href="#" class="hover:text-gray-600">服务条款</a>
      </div>
    </footer>
  </main>
</body>
</html>

这个页面里用了这些布局技巧:

  • fixed top-0 inset-x-0 —— 导航栏固定在顶部
  • flex items-center justify-between —— 导航栏左右布局,Logo 在左,链接在右
  • flex-col items-center —— Hero 区域垂直居中
  • grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 —— 响应式卡片网格:手机 1 列,平板 2 列,桌面 3 列
  • flex items-center justify-between —— 页脚左右分布
本章小结
  • Flex 是一维布局,flex + justify-* + items-* 三件套搞定大部分场景
  • Grid 是二维布局,grid-cols-* 配合 gap-* 做卡片网格
  • flex-1 等比例分配空间,flex-auto 按内容分配
  • 定位方式:fixed 固定、sticky 粘性、absolute 绝对
  • items-center 是实现垂直居中的核心类

布局搭起来了,但卡片看起来还有点"平"。下一篇,我们来添加边框、圆角和阴影,让元素更有质感。

目录