第35课:Tailwind CSS 布局与响应式——Flex/Grid 类、断点前缀、container、@apply
Tailwind CSS 将 CSS 的 Flexbox 和 Grid 能力封装为直观的原子类,结合响应式前缀,让你无需写一行 CSS 即可构建任意复杂的自适应布局。本节课将系统讲解 Tailwind 中的 Flex 和 Grid 工具类体系、断点前缀的精细控制、container 容器的用法,以及如何通过 @apply 将高频布局模式抽象为可复用的组件类。掌握这些工具后,你将能够在 HTML 中以极快的速度实现从导航栏到仪表板的全部布局需求。
1. Flexbox 工具类:一维布局的原子化控制
Tailwind 提供了一套完整的 Flexbox 工具类,命名与 CSS 属性直接对应,并支持响应式前缀。所有类均作用于容器(设置 flex)或项目(子元素)。
1.1 开启 Flex 容器
1 | <div class="flex"> |
1.2 方向与换行
| 类名 | CSS 属性 | 说明 |
|---|---|---|
flex-row |
flex-direction: row |
水平排列(默认) |
flex-row-reverse |
flex-direction: row-reverse |
水平反向排列 |
flex-col |
flex-direction: column |
垂直排列 |
flex-col-reverse |
flex-direction: column-reverse |
垂直反向排列 |
flex-wrap |
flex-wrap: wrap |
允许换行 |
flex-wrap-reverse |
flex-wrap: wrap-reverse |
反向换行 |
flex-nowrap |
flex-wrap: nowrap |
不换行(默认) |
1 | <!-- 响应式:移动端垂直堆叠,桌面端水平排列 --> |
1.3 主轴对齐:justify-*
| 类名 | CSS 值 | 说明 |
|---|---|---|
justify-start |
flex-start |
项目紧靠主轴起点。 |
justify-end |
flex-end |
项目紧靠主轴终点。 |
justify-center |
center |
项目居中于主轴。 |
justify-between |
space-between |
两端对齐,中间均分空白。 |
justify-around |
space-around |
每个项目两侧间距相等。 |
justify-evenly |
space-evenly |
所有间距完全相等。 |
1 | <!-- 导航栏:Logo 靠左,链接靠右 --> |
1.4 交叉轴对齐:items-* 与 content-*
| 类名 | CSS 值 | 作用对象 |
|---|---|---|
items-start |
flex-start |
单行内所有项目。 |
items-center |
center |
垂直居中(最常用)。 |
items-end |
flex-end |
靠交叉轴终点。 |
items-stretch |
stretch(默认) |
拉伸以填满交叉轴。 |
items-baseline |
baseline |
基线对齐。 |
content-* 用于多行容器(需 flex-wrap),控制行组在交叉轴的分布:
| 类名 | CSS 值 |
|---|---|
content-start |
flex-start |
content-center |
center |
content-between |
space-between |
content-around |
space-around |
content-evenly |
space-evenly |
1.5 项目自身控制
| 类名 | CSS 属性 / 值 | 说明 |
|---|---|---|
flex-1 |
flex: 1 1 0% |
弹性填充剩余空间(等分列)。 |
flex-auto |
flex: 1 1 auto |
基于内容宽度弹性伸缩。 |
flex-initial |
flex: 0 1 auto |
允许收缩但不增长。 |
flex-none |
flex: none |
固定尺寸,不伸缩。 |
flex-shrink-0 |
flex-shrink: 0 |
禁止收缩(如固定侧边栏)。 |
flex-grow-0 |
flex-grow: 0 |
禁止增长。 |
self-auto |
align-self: auto |
继承容器的 items-* 设置。 |
self-start |
align-self: flex-start |
单个项目靠交叉轴起点。 |
self-center |
align-self: center |
单个项目交叉轴居中。 |
self-end |
align-self: flex-end |
单个项目靠交叉轴终点。 |
self-stretch |
align-self: stretch |
单个项目拉伸。 |
1 | <!-- 固定侧边栏 + 弹性主体内容 --> |
1.6 间距:gap-*
Tailwind 的 gap 类直接设置 Flex/Grid 容器中项目之间的间距,数值基于配置文件中的间距尺度。
1 | <div class="flex gap-4"> |
| 类名 | 对应值 | 类名 | 对应值 |
|---|---|---|---|
gap-0 |
0 | gap-4 |
1rem |
gap-1 |
0.25rem | gap-6 |
1.5rem |
gap-2 |
0.5rem | gap-8 |
2rem |
gap-3 |
0.75rem | gap-12 |
3rem |
gap-x-* 和 gap-y-* 分别控制水平和垂直间距。
2. Grid 工具类:二维布局的声明式控制
Tailwind 的 Grid 工具类建立在 CSS Grid 之上,核心类直接映射 grid-template-columns 等属性。
2.1 定义网格列数
使用 grid-cols-{n} 定义显式列数,n 从 1 到 12。
1 | <div class="grid grid-cols-3 gap-4"> |
grid-cols-none 恢复为默认行为(不定义显式列)。
响应式列数:
1 | <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> |
2.2 隐式行高:auto-rows-*
当网格项超出自定义的列数限制时,新行会由隐式网格自动生成。auto-rows-* 设置这些自动行的默认高度。
1 | <div class="grid grid-cols-3 auto-rows-min gap-4"> |
2.3 列跨度与行跨度
使用 col-span-{n} 和 row-span-{n} 让项目跨越多个轨道。
1 | <div class="grid grid-cols-4 gap-4"> |
col-span-full:占满整行所有列。col-start-{n}/col-end-{n}:通过网格线号精确控制起始和结束位置。
2.4 对齐控制
与 Flex 类似,Grid 也提供对齐类。作用范围包括容器内所有项目(place-items-*)和单个项目(place-self-*)。
| 类名 | 作用 |
|---|---|
place-items-center |
所有项目在单元格内水平和垂直居中。 |
place-items-start |
靠左上角。 |
place-items-end |
靠右下角。 |
place-self-center |
单个项目在单元格内居中。 |
place-content-center |
整个网格在容器内居中(当网格总尺寸小于容器时生效)。 |
3. 响应式前缀与断点体系
3.1 断点对应表
| 前缀 | 最小宽度 | 典型场景 |
|---|---|---|
sm |
640px | 大屏手机横屏。 |
md |
768px | 平板竖屏。 |
lg |
1024px | 平板横屏 / 小型桌面。 |
xl |
1280px | 桌面显示器。 |
2xl |
1536px | 大屏桌面。 |
重要:Tailwind 遵循移动优先策略。不带前缀的类作用于所有屏幕(从小屏开始),带前缀的类在指定断点及以上生效。
1 | <!-- 基础样式(手机):文字小,单列 --> |
3.2 区间响应式(仅在某断点之间生效)
若希望某样式仅在 md 到 lg 之间生效,可用 max-* 前缀(Tailwind v3.2+ 内置)。
1 | <div class="bg-white md:max-lg:bg-yellow-100"> |
md:max-lg:等价于 CSS 的@media (min-width: 768px) and (max-width: 1023px)。
3.3 自定义断点
在 tailwind.config.js 的 theme.extend.screens 中可添加自定义断点或覆盖默认值:
1 | // tailwind.config.js |
使用:3xl:grid-cols-6、tall:items-center。
4. container 组件:居中固定宽度的包装器
Tailwind 的 container 类与 Bootstrap 的 .container 类似:在某个断点以下为全宽,达到断点后变为固定的最大宽度并水平居中。
1 | <div class="container mx-auto px-4"> |
默认行为:
- 在所有断点下均为
width: 100%(不会自动居中),需配合mx-auto实现居中。 - 各断点对应的最大宽度:
| 断点 | 最大宽度 |
|---|---|
| 默认 | 100% |
sm |
640px |
md |
768px |
lg |
1024px |
xl |
1280px |
2xl |
1536px |
**在配置中自定义 container**:
1 | // tailwind.config.js |
5. @apply 提取布局模式
当某个布局组合(如“水平居中、两端对齐的导航栏”)在项目中高频出现时,可用 @apply 将其提取为一个语义化类。
提取前(原始 Tailwind 写法):
1 | <nav class="flex justify-between items-center px-6 py-4 bg-gray-900 text-white"> |
提取后(@apply 在 CSS 中):
1 | @layer components { |
1 | <nav class="navbar"> |
**何时使用 @apply**:
- 同一种布局模式出现在5 个以上不同位置。
- 该布局具有明确的语义含义(如
.dashboard-sidebar、.product-grid)。 - 需要在该布局上添加额外的 CSS(如过渡动画、
::before伪元素)。
**何时避免 @apply**:
- 仅出现 1-2 次的临时布局——直接使用原子类更清晰。
- 仅为了“让 HTML 看起来更干净”——组件化(React/Vue)本身就是复用的最佳载体。
6. 综合示例:仪表板布局
1 |
|
关键布局技术总结:
- 顶部导航:
flex justify-between+ 响应式隐藏导航链接(hidden md:flex)和汉堡图标(md:hidden)。 - 主体区域:
flex flex-col lg:flex-row,移动端垂直堆叠,桌面端侧边栏与主内容并排。 - 侧边栏:
hidden lg:flex,移动端隐藏,桌面端显示为垂直 Flex 容器。 - 统计卡片:
grid-cols-1 sm:grid-cols-2 xl:grid-cols-4,逐级增加列数。 - 图表+表格:
grid-cols-1 lg:grid-cols-3+lg:col-span-2,让图表占据更多空间。
课后练习
一、概念自测(选择题 / 填空题)
(单选) 在 Tailwind 中,类名
md:flex-row的含义是?
A. 仅在屏幕宽度恰好为 768px 时,Flex 方向为行。
B. 在屏幕宽度 ≥ 768px 时,Flex 方向为行。
C. 在屏幕宽度 < 768px 时,Flex 方向为行。
D. 在所有屏幕宽度下,Flex 方向均为行。(单选) 要使一个 Grid 容器在移动端为 1 列、平板(≥768px)为 2 列、桌面(≥1024px)为 4 列,正确的类名组合是?
A.grid-cols-1 sm:grid-cols-2 lg:grid-cols-4
B.grid-cols-1 md:grid-cols-2 lg:grid-cols-4
C.grid-cols-1 md:grid-cols-2 xl:grid-cols-4
D.grid-cols-1 sm:grid-cols-2 xl:grid-cols-4(填空) 在 Tailwind 中,要使一个 Flex 项目的子元素在交叉轴上单独底部对齐,应使用类名
______。(多选) 关于 Tailwind 的
container组件,以下哪些说法正确?
A. 默认行为下,需要配合mx-auto才能水平居中。
B. 它在各断点处有不同的最大宽度。
C. 它自动为其内部的栅格项目提供间隙。
D. 在配置中设置center: true可省略mx-auto。
二、AI 编程任务:编写面向 AI 的提示词
场景:你需要使用 Tailwind CSS 构建一个博客文章列表页的响应式布局。要求如下:
- 使用 Tailwind CDN 引入。
- 页面头部:标题“我的博客”和一段简短副标题,居中显示。
- 主体区域:使用 Grid 布局,移动端 1 列,平板(≥768px)2 列,桌面(≥1024px)3 列。
- 每篇文章卡片包含:一张 16:9 占位图片、文章标题、日期、摘要文字(限制 3 行后省略)。
- 卡片之间有统一的间距,卡片白色背景,圆角,轻微阴影,悬停时阴影加深。
- 页面底部有一个“加载更多”按钮,水平居中。
- 所有样式完全使用 Tailwind 原子类实现,无自定义 CSS。
任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成符合上述要求的完整 HTML 文件。提示词中需明确指定 Grid 布局的响应式列数、卡片各元素的具体类名、以及悬停交互效果。
课后练习答案
一、概念自测答案
B
- 解析:Tailwind 使用移动优先,
md:前缀表示在 768px 及以上断点生效。
- 解析:Tailwind 使用移动优先,
B
- 解析:
md对应 768px,lg对应 1024px。sm是 640px,不符合要求。
- 解析:
self-end- 解析:
self-end对应 CSS 的align-self: flex-end,使单个项目在交叉轴上靠底部对齐。
- 解析:
A、B、D
- 解析:A 正确,默认
container仅为width: 100%,需mx-auto居中;B 正确,各断点有不同max-width;D 正确,配置中center: true自动居中。C 错误,container不控制内部项目间隙,间隙由gap类或子元素的 margin/padding 控制。
- 解析:A 正确,默认
二、AI 编程任务参考答案(提示词示例)
示例提示词:
“请使用 Tailwind CSS CDN 构建一个博客文章列表页。要求:
- 使用
<script src="https://cdn.tailwindcss.com"></script>引入。- 头部:
<header class="text-center py-12">,内含<h1 class="text-4xl font-bold text-gray-900">我的博客</h1>和<p class="text-gray-500 mt-2">分享前端技术心得</p>。- 主体:
<main class="container mx-auto px-4">,内含一个<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">。- 每篇卡片:
<article class="bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-shadow">。- 卡片内:
<img class="w-full aspect-video object-cover" src="https://via.placeholder.com/640x360">,下方<div class="p-5">包裹标题<h2 class="text-xl font-semibold text-gray-900">、日期<p class="text-sm text-gray-500 mt-1">、摘要<p class="text-gray-600 mt-3 line-clamp-3">。- 至少包含 6 篇文章卡片(可重复结构)。
- 底部:
<div class="text-center py-10"><button class="bg-indigo-600 text-white px-8 py-3 rounded-lg hover:bg-indigo-700 transition-colors">加载更多</button></div>。- 所有样式完全使用 Tailwind 类,无任何自定义 CSS。直接输出完整 HTML 文件。”