Skip to content

布局系统

布局是 CSS 的核心能力,也是 TailwindCSS 最常用的功能之一。Tailwind 提供了完整的 Flexbox、Grid、定位系统工具类,让你无需编写自定义 CSS 就能实现任意复杂度的页面布局。本文将系统性地介绍这些布局工具类的使用方法和实战技巧。

Display 显示类型#

控制元素如何在文档流中呈现:

<!-- 块级元素 -->
<div class="block">块级元素,独占一行</div>
<!-- 行内元素 -->
<span class="inline">行内元素</span>
<!-- 行内块 -->
<div class="inline-block">行内块元素</div>
<!-- Flex 容器 -->
<div class="flex">Flex 容器</div>
<!-- 行内 Flex -->
<div class="inline-flex">行内 Flex 容器</div>
<!-- Grid 容器 -->
<div class="grid">Grid 容器</div>
<!-- 行内 Grid -->
<div class="inline-grid">行内 Grid 容器</div>
<!-- 隐藏元素 -->
<div class="hidden">不渲染</div>

完整的 display 工具类:

类名CSS 属性
blockdisplay: block
inlinedisplay: inline
inline-blockdisplay: inline-block
flexdisplay: flex
inline-flexdisplay: inline-flex
griddisplay: grid
inline-griddisplay: inline-grid
contentsdisplay: contents
hiddendisplay: none
tabledisplay: table
table-rowdisplay: table-row
table-celldisplay: table-cell

Flexbox 弹性布局#

Flexbox 是现代 CSS 布局的基石。Tailwind 提供了完整的 Flex 工具类。

基础用法#

function FlexDemo() {
return (
// flex: 启用 Flex 布局
<div className="flex">
<div className="w-16 h-16 bg-blue-500">1</div>
<div className="w-16 h-16 bg-blue-400">2</div>
<div className="w-16 h-16 bg-blue-300">3</div>
</div>
)
}

主轴方向 (flex-direction)#

<!-- 水平排列(默认) -->
<div class="flex flex-row">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 水平反向 -->
<div class="flex flex-row-reverse">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 垂直排列 -->
<div class="flex flex-col">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 垂直反向 -->
<div class="flex flex-col-reverse">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

换行控制 (flex-wrap)#

<!-- 不换行(默认) -->
<div class="flex flex-nowrap">...</div>
<!-- 换行 -->
<div class="flex flex-wrap">...</div>
<!-- 反向换行 -->
<div class="flex flex-wrap-reverse">...</div>

主轴对齐 (justify-content)#

控制子元素在主轴(默认水平方向)上的对齐方式:

<!-- 起点对齐 -->
<div class="flex justify-start">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 居中对齐 -->
<div class="flex justify-center">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 终点对齐 -->
<div class="flex justify-end">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 两端对齐 -->
<div class="flex justify-between">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 均匀分布(元素周围间距相等) -->
<div class="flex justify-around">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 均匀分布(元素之间间距相等) -->
<div class="flex justify-evenly">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

可视化对比:

justify-start: |1 2 3 |
justify-center: | 1 2 3 |
justify-end: | 1 2 3|
justify-between: |1 2 3|
justify-around: | 1 2 3 |
justify-evenly: | 1 2 3 |

交叉轴对齐 (align-items)#

控制子元素在交叉轴(默认垂直方向)上的对齐方式:

<!-- 拉伸填满(默认) -->
<div class="flex items-stretch h-32">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 起点对齐 -->
<div class="flex items-start h-32">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 居中对齐 -->
<div class="flex items-center h-32">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 终点对齐 -->
<div class="flex items-end h-32">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 基线对齐 -->
<div class="flex items-baseline h-32">
<div class="text-sm"></div>
<div class="text-2xl"></div>
<div class="text-base"></div>
</div>

水平垂直居中#

最常见的布局需求——完美居中:

function CenterDemo() {
return (
<div className="flex items-center justify-center h-screen bg-gray-100">
<div className="p-8 bg-white rounded-xl shadow-lg">我被完美居中了</div>
</div>
)
}

子元素伸缩 (flex-grow / flex-shrink)#

<!-- flex-1: 等比例填充剩余空间 -->
<div class="flex">
<div class="w-20 bg-blue-300">固定宽度</div>
<div class="flex-1 bg-blue-500">填充剩余空间</div>
<div class="w-20 bg-blue-300">固定宽度</div>
</div>
<!-- 不同比例分配 -->
<div class="flex">
<div class="flex-1 bg-blue-300">1份</div>
<div class="flex-2 bg-blue-500">2份</div>
<div class="flex-1 bg-blue-300">1份</div>
</div>
<!-- 禁止收缩 -->
<div class="flex">
<div class="shrink-0 w-48">不会被压缩</div>
<div class="flex-1">可能被压缩</div>
</div>
<!-- 禁止增长 -->
<div class="flex">
<div class="grow-0">不会增长</div>
<div class="flex-1">填充剩余</div>
</div>

flex 工具类速查:

类名CSS说明
flex-1flex: 1 1 0%等比例增长和收缩
flex-autoflex: 1 1 auto基于内容的弹性
flex-initialflex: 0 1 auto不增长但可收缩
flex-noneflex: none不增长也不收缩

子元素排序 (order)#

<div class="flex">
<div class="order-3">显示在第三</div>
<div class="order-1">显示在第一</div>
<div class="order-2">显示在第二</div>
</div>

Gap 间距#

v4 中推荐使用 gap 而非 space-x/y

<!-- 统一间距 -->
<div class="flex gap-4">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 分别设置行列间距 -->
<div class="flex flex-wrap gap-x-4 gap-y-2">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

Grid 网格布局#

Grid 布局适合处理二维布局场景。

定义网格#

<!-- 3列等宽网格 -->
<div class="grid grid-cols-3 gap-4">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<!-- 4列等宽网格 -->
<div class="grid grid-cols-4 gap-4">...</div>
<!-- 自定义列宽 -->
<div class="grid grid-cols-[200px_1fr_200px] gap-4">
<div>固定200px</div>
<div>弹性填充</div>
<div>固定200px</div>
</div>

预设的列数:grid-cols-1grid-cols-12,以及 grid-cols-none

行定义#

<!-- 3行等高 -->
<div class="grid grid-rows-3 gap-4">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<!-- 自定义行高 -->
<div class="grid grid-rows-[auto_1fr_auto] min-h-screen">
<header>Header</header>
<main>Content</main>
<footer>Footer</footer>
</div>

响应式网格#

<!-- 移动端1列,平板2列,桌面3列,大屏4列 -->
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
>
<div class="p-4 bg-white rounded-lg shadow">卡片1</div>
<div class="p-4 bg-white rounded-lg shadow">卡片2</div>
<div class="p-4 bg-white rounded-lg shadow">卡片3</div>
<div class="p-4 bg-white rounded-lg shadow">卡片4</div>
</div>

跨列跨行#

<div class="grid grid-cols-4 gap-4">
<!-- 跨2列 -->
<div class="col-span-2 bg-blue-500">跨2列</div>
<div class="bg-blue-300">1列</div>
<div class="bg-blue-300">1列</div>
<!-- 跨4列(整行) -->
<div class="col-span-4 bg-blue-600">整行</div>
<!-- 从第2列开始,跨2列 -->
<div class="col-start-2 col-span-2 bg-blue-400">第2-3列</div>
</div>

跨列/跨行工具类:

col-span-{n} : 跨 n 列
col-start-{n} : 从第 n 列开始
col-end-{n} : 在第 n 列结束
row-span-{n} : 跨 n 行
row-start-{n} : 从第 n 行开始
row-end-{n} : 在第 n 行结束

自动填充网格#

<!-- 自动填充,每列最小200px -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-4">
<div>卡片</div>
<div>卡片</div>
<div>卡片</div>
<!-- 会根据容器宽度自动调整列数 -->
</div>
<!-- 自动适应 -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-4">
<div>卡片</div>
<div>卡片</div>
</div>

auto-fill vs auto-fit

Grid 对齐#

<!-- 整体内容对齐 -->
<div class="grid place-content-center h-64">
<div>居中内容</div>
</div>
<!-- 单元格内容对齐 -->
<div class="grid place-items-center h-64 grid-cols-3">
<div>居中</div>
<div>居中</div>
<div>居中</div>
</div>
<!-- 单独控制某个子元素 -->
<div class="grid grid-cols-3">
<div class="place-self-center">这个居中</div>
<div class="place-self-start">这个靠左上</div>
<div class="place-self-end">这个靠右下</div>
</div>

Container 容器#

container 类提供响应式的最大宽度约束:

<div class="container mx-auto px-4">
<!-- 内容会在不同断点有不同的最大宽度 -->
</div>

默认断点下的容器宽度:

断点最大宽度
100%
sm (640px)640px
md (768px)768px
lg (1024px)1024px
xl (1280px)1280px
2xl (1536px)1536px

自定义容器配置(在 CSS 中):

@theme {
--container-padding: 1rem;
--container-max-width-sm: 600px;
--container-max-width-lg: 960px;
}

Position 定位#

定位类型#

<!-- 静态定位(默认) -->
<div class="static">...</div>
<!-- 相对定位 -->
<div class="relative">...</div>
<!-- 绝对定位 -->
<div class="absolute">...</div>
<!-- 固定定位 -->
<div class="fixed">...</div>
<!-- 粘性定位 -->
<div class="sticky">...</div>

位置控制#

<!-- 四角定位 -->
<div class="absolute top-0 left-0">左上角</div>
<div class="absolute top-0 right-0">右上角</div>
<div class="absolute bottom-0 left-0">左下角</div>
<div class="absolute bottom-0 right-0">右下角</div>
<!-- 居中定位 -->
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
绝对居中
</div>
<!-- 简写:inset -->
<div class="absolute inset-0">填满父容器</div>
<div class="absolute inset-x-0 top-0">顶部横条</div>
<div class="absolute inset-y-0 right-0">右侧竖条</div>

位置值可以是:

堆叠顺序 (z-index)#

<div class="relative">
<div class="absolute z-10">层级 10</div>
<div class="absolute z-20">层级 20(在上面)</div>
<div class="absolute z-0">层级 0</div>
<div class="absolute -z-10">层级 -10(在最下面)</div>
</div>

预设值:z-0, z-10, z-20, z-30, z-40, z-50, z-auto

3D 变换与透视#

v4 新增了完整的 3D 变换支持:

<!-- 透视容器 -->
<div class="perspective-dramatic">
<!-- dramatic: 近距离视角,3D 效果强烈 -->
<div class="rotate-y-12 translate-z-8">3D 卡片</div>
</div>
<div class="perspective-normal">
<!-- normal: 正常视角 -->
<div class="rotate-x-6 -translate-z-4">3D 元素</div>
</div>

3D 变换工具类:

类名说明
perspective-*设置透视距离
translate-z-*Z 轴位移(正值向前)
rotate-x-*X 轴旋转
rotate-y-*Y 轴旋转
transform-3d启用 3D 变换空间
backface-hidden隐藏背面(翻转卡片常用)

3D 翻转卡片示例:

function FlipCard({
front,
back,
}: {
front: React.ReactNode
back: React.ReactNode
}) {
return (
<div className="group perspective-normal w-64 h-40">
<div className="relative w-full h-full transition-transform duration-500 transform-3d group-hover:rotate-y-180">
{/* 正面 */}
<div className="absolute inset-0 backface-hidden bg-white rounded-xl shadow-lg p-4">
{front}
</div>
{/* 背面 */}
<div className="absolute inset-0 backface-hidden rotate-y-180 bg-blue-500 text-white rounded-xl shadow-lg p-4">
{back}
</div>
</div>
</div>
)
}

粘性定位示例#

function StickyHeader() {
return (
<div>
<header className="sticky top-0 z-50 bg-white/80 backdrop-blur-sm border-b">
<nav className="container mx-auto px-4 h-16 flex items-center">
<span className="font-bold">Logo</span>
</nav>
</header>
<main className="container mx-auto px-4 py-8">{/* 长内容 */}</main>
</div>
)
}

实战:常见布局模式#

圣杯布局#

function HolyGrailLayout() {
return (
<div className="min-h-screen flex flex-col">
{/* Header */}
<header className="h-16 bg-gray-900 text-white flex items-center px-6">
<h1 className="text-xl font-bold">网站标题</h1>
</header>
{/* Main content area */}
<div className="flex-1 flex">
{/* Left sidebar */}
<aside className="w-64 bg-gray-100 p-4 hidden lg:block">
<nav className="space-y-2">
<a href="#" className="block px-4 py-2 rounded hover:bg-gray-200">
链接1
</a>
<a href="#" className="block px-4 py-2 rounded hover:bg-gray-200">
链接2
</a>
</nav>
</aside>
{/* Main content */}
<main className="flex-1 p-6">
<h2 className="text-2xl font-bold mb-4">主要内容</h2>
<p className="text-gray-600">这里是页面的主要内容区域...</p>
</main>
{/* Right sidebar */}
<aside className="w-64 bg-gray-50 p-4 hidden xl:block">
<h3 className="font-bold mb-4">侧边栏</h3>
<p className="text-sm text-gray-600">附加信息...</p>
</aside>
</div>
{/* Footer */}
<footer className="h-16 bg-gray-900 text-white flex items-center justify-center">
<p className="text-sm">© 2025 版权所有</p>
</footer>
</div>
)
}

卡片网格#

interface Card {
id: number
title: string
description: string
image: string
}
function CardGrid({ cards }: { cards: Card[] }) {
return (
<div className="container mx-auto px-4 py-8">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{cards.map((card) => (
<article
key={card.id}
className="group bg-white rounded-xl shadow-sm hover:shadow-lg transition-shadow overflow-hidden"
>
<div className="aspect-video overflow-hidden">
<img
src={card.image}
alt={card.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
/>
</div>
<div className="p-4">
<h3 className="font-bold text-lg mb-2 line-clamp-1">
{card.title}
</h3>
<p className="text-gray-600 text-sm line-clamp-2">
{card.description}
</p>
</div>
</article>
))}
</div>
</div>
)
}

瀑布流布局#

使用 CSS columns 实现简单瀑布流:

function MasonryLayout({ items }: { items: React.ReactNode[] }) {
return (
<div className="columns-1 sm:columns-2 lg:columns-3 xl:columns-4 gap-4 space-y-4">
{items.map((item, index) => (
<div key={index} className="break-inside-avoid">
{item}
</div>
))}
</div>
)
}

固定宽高比容器#

<!-- 16:9 视频容器 -->
<div class="aspect-video bg-gray-200">
<iframe class="w-full h-full" src="..."></iframe>
</div>
<!-- 1:1 正方形 -->
<div class="aspect-square bg-gray-200">
<img class="w-full h-full object-cover" src="..." />
</div>
<!-- 4:3 -->
<div class="aspect-[4/3] bg-gray-200">...</div>
<!-- 自定义比例 -->
<div class="aspect-[21/9] bg-gray-200">超宽屏</div>
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null
return (
<div className="fixed inset-0 z-50">
{/* 背景遮罩 */}
<div
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
onClick={onClose}
/>
{/* 弹窗内容 */}
<div className="absolute inset-0 flex items-center justify-center p-4">
<div className="relative bg-white rounded-2xl shadow-2xl max-w-lg w-full max-h-[90vh] overflow-auto">
{/* 关闭按钮 */}
<button
onClick={onClose}
className="absolute top-4 right-4 w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-100"
>
</button>
<div className="p-6">{children}</div>
</div>
</div>
</div>
)
}

布局调试技巧#

可视化边界#

开发时临时添加边框查看布局:

<!-- 添加边框调试 -->
<div class="border border-red-500">...</div>
<!-- 或使用背景色 -->
<div class="bg-red-100">...</div>

使用开发者工具#

在浏览器开发者工具中:

Tailwind CSS IntelliSense#

编辑器插件可以实时预览工具类对应的 CSS,方便理解布局效果。


掌握了布局系统,你已经能够构建绝大多数页面结构。下一篇文章,我们将深入探讨间距与尺寸系统,了解 Tailwind 的间距设计哲学和各种尺寸工具类的使用技巧。