TailwindCSS 的间距系统建立在一套精心设计的比例之上。这套系统以 4px 为基准单位,通过倍数关系构建出和谐的视觉节奏。理解这套系统,是写出优雅 Tailwind 代码的关键。
间距比例系统#
Tailwind 默认的间距比例基于 4px(0.25rem),这是一套经过验证的设计系统:
| 类名后缀 | 值 | 像素值 | 常用场景 |
|---|---|---|---|
0 | 0 | 0px | 清除间距 |
1 | 0.25rem | 4px | 紧凑间距 |
2 | 0.5rem | 8px | 小间距 |
4 | 1rem | 16px | 标准间距 |
6 | 1.5rem | 24px | 组件内间距 |
8 | 2rem | 32px | 区块间距 |
12 | 3rem | 48px | 大区块间距 |
16 | 4rem | 64px | 区域分隔 |
24 | 6rem | 96px | 主要区块 |
完整比例:
0, px, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
这套比例同时应用于 padding、margin、gap、width、height 等多种属性。
Padding 内边距#
基础用法#
<!-- 四边等距 --><div class="p-4">四边 16px 内边距</div>
<!-- 水平/垂直 --><div class="px-4 py-2">左右 16px,上下 8px</div>
<!-- 单边 --><div class="pt-4">上边距 16px</div><div class="pr-4">右边距 16px</div><div class="pb-4">下边距 16px</div><div class="pl-4">左边距 16px</div>类名规则:
p-{n}: 四边px-{n}: 水平(左右)py-{n}: 垂直(上下)pt-{n}: 上pr-{n}: 右pb-{n}: 下pl-{n}: 左
逻辑属性#
v4 支持逻辑属性,适配不同书写方向(LTR/RTL):
<!-- 逻辑方向的内边距 --><div class="ps-4">start 方向 16px(LTR 时等于 pl-4)</div><div class="pe-4">end 方向 16px(LTR 时等于 pr-4)</div>实际应用#
function Card({ children }: { children: React.ReactNode }) { return ( // p-6: 内容与边框保持舒适距离 <div className="p-6 bg-white rounded-xl shadow-sm">{children}</div> )}
function Button({ children }: { children: React.ReactNode }) { return ( // px-4 py-2: 按钮的标准内边距比例 <button className="px-4 py-2 bg-blue-500 text-white rounded-lg"> {children} </button> )}
function ListItem({ children }: { children: React.ReactNode }) { return ( // py-3 px-4: 列表项的舒适点击区域 <li className="py-3 px-4 hover:bg-gray-50 cursor-pointer">{children}</li> )}Margin 外边距#
基础用法#
<!-- 四边等距 --><div class="m-4">四边 16px 外边距</div>
<!-- 水平/垂直 --><div class="mx-4 my-2">左右 16px,上下 8px</div>
<!-- 单边 --><div class="mt-4">上外边距 16px</div><div class="mr-4">右外边距 16px</div><div class="mb-4">下外边距 16px</div><div class="ml-4">左外边距 16px</div>负边距#
Tailwind 支持负边距,在类名前加 -:
<!-- 负边距:向上移动 --><div class="-mt-4">上移 16px</div>
<!-- 负边距:突破容器边界 --><div class="p-6 bg-gray-100"> <div class="-mx-6 bg-blue-500 p-4">我突破了父容器的左右边界</div></div>负边距的典型应用场景:
function OverflowImage() { return ( <article className="p-6 bg-white rounded-xl"> <h2 className="text-xl font-bold mb-4">文章标题</h2> {/* 图片突破文章内边距,实现全宽效果 */} <img src="/hero.jpg" alt="Hero" className="-mx-6 w-[calc(100%+3rem)] max-w-none" /> <p className="mt-4 text-gray-600">正文内容...</p> </article> )}自动边距#
auto 值用于水平居中或推到一侧:
<!-- 水平居中 --><div class="mx-auto w-64">我被水平居中了</div>
<!-- 推到右侧 --><div class="ml-auto w-fit">我被推到右侧</div>
<!-- Flexbox 中的自动边距 --><nav class="flex items-center"> <span class="font-bold">Logo</span> <div class="ml-auto flex gap-4"> <a href="#">链接1</a> <a href="#">链接2</a> </div></nav>Space Between 子元素间距#
space-x 和 space-y 为相邻子元素添加间距:
<!-- 水平间距 --><div class="flex space-x-4"> <div>1</div> <div>2</div> <div>3</div></div>
<!-- 垂直间距 --><div class="flex flex-col space-y-4"> <div>1</div> <div>2</div> <div>3</div></div>实现原理是给除第一个外的所有子元素添加 margin:
.space-x-4 > * + * { margin-left: 1rem;}space vs gap#
现代布局更推荐使用 gap:
<!-- 推荐:使用 gap --><div class="flex gap-4"> <div>1</div> <div>2</div> <div>3</div></div>
<!-- 不推荐:使用 space-x --><div class="flex space-x-4"> <div>1</div> <div>2</div> <div>3</div></div>gap 的优势:
- 不依赖 margin,避免与其他样式冲突
- 在 Grid 布局中工作一致
- 元素被隐藏时间距自动调整
- 支持
gap-x和gap-y分别控制
Width 宽度#
固定宽度#
<!-- 使用间距比例 --><div class="w-4">16px 宽</div><div class="w-64">256px 宽</div><div class="w-96">384px 宽</div>
<!-- 任意值 --><div class="w-[200px]">200px 宽</div><div class="w-[30rem]">30rem 宽</div>相对宽度#
<!-- 百分比 --><div class="w-1/2">50% 宽</div><div class="w-1/3">33.333% 宽</div><div class="w-2/3">66.667% 宽</div><div class="w-1/4">25% 宽</div><div class="w-3/4">75% 宽</div><div class="w-full">100% 宽</div>
<!-- 视口相对 --><div class="w-screen">100vw 宽</div><div class="w-svw">100svw(小视口宽度)</div><div class="w-lvw">100lvw(大视口宽度)</div><div class="w-dvw">100dvw(动态视口宽度)</div>内容自适应#
<!-- 根据内容自动 --><div class="w-auto">自动宽度</div>
<!-- 最小内容宽度 --><div class="w-min">min-content</div>
<!-- 最大内容宽度 --><div class="w-max">max-content</div>
<!-- fit-content --><div class="w-fit">fit-content</div>min-width / max-width#
<!-- 最小宽度 --><div class="min-w-0">min-width: 0</div><div class="min-w-full">min-width: 100%</div><div class="min-w-[300px]">min-width: 300px</div>
<!-- 最大宽度 --><div class="max-w-xs">max-width: 20rem (320px)</div><div class="max-w-sm">max-width: 24rem (384px)</div><div class="max-w-md">max-width: 28rem (448px)</div><div class="max-w-lg">max-width: 32rem (512px)</div><div class="max-w-xl">max-width: 36rem (576px)</div><div class="max-w-2xl">max-width: 42rem (672px)</div><div class="max-w-3xl">max-width: 48rem (768px)</div><div class="max-w-4xl">max-width: 56rem (896px)</div><div class="max-w-5xl">max-width: 64rem (1024px)</div><div class="max-w-6xl">max-width: 72rem (1152px)</div><div class="max-w-7xl">max-width: 80rem (1280px)</div><div class="max-w-full">max-width: 100%</div><div class="max-w-none">max-width: none</div>常见的内容容器模式:
function PageContainer({ children }: { children: React.ReactNode }) { return ( // max-w-4xl: 限制内容最大宽度 // mx-auto: 水平居中 // px-4: 移动端留出边距 <div className="max-w-4xl mx-auto px-4">{children}</div> )}Height 高度#
固定高度#
<!-- 使用间距比例 --><div class="h-4">16px 高</div><div class="h-64">256px 高</div><div class="h-96">384px 高</div>
<!-- 任意值 --><div class="h-[200px]">200px 高</div>相对高度#
<!-- 百分比 --><div class="h-1/2">50% 高</div><div class="h-full">100% 高</div>
<!-- 视口相对 --><div class="h-screen">100vh 高</div><div class="h-svh">100svh(小视口高度)</div><div class="h-lvh">100lvh(大视口高度)</div><div class="h-dvh">100dvh(动态视口高度)</div>移动端视口高度的问题与解决:
// 移动端浏览器地址栏会影响 100vh// 使用 dvh 动态视口高度更准确function FullScreenHero() { return ( <section className="h-dvh flex items-center justify-center bg-gradient-to-br from-blue-500 to-purple-600"> <h1 className="text-4xl font-bold text-white">全屏 Hero</h1> </section> )}min-height / max-height#
<!-- 最小高度 --><div class="min-h-0">min-height: 0</div><div class="min-h-full">min-height: 100%</div><div class="min-h-screen">min-height: 100vh</div><div class="min-h-dvh">min-height: 100dvh</div>
<!-- 最大高度 --><div class="max-h-64">max-height: 256px</div><div class="max-h-full">max-height: 100%</div><div class="max-h-screen">max-height: 100vh</div>Size 同时设置宽高#
v4 新增 size-* 工具类,同时设置宽度和高度:
<!-- 正方形 --><div class="size-4">16px × 16px</div><div class="size-8">32px × 32px</div><div class="size-16">64px × 64px</div>
<!-- 常见的图标/头像尺寸 --><div class="size-6">24px 小图标</div><div class="size-10">40px 头像</div><div class="size-12">48px 大头像</div>
<!-- 任意值 --><div class="size-[100px]">100px × 100px</div>
<!-- 相对值 --><div class="size-full">100% × 100%</div>应用示例:
function Avatar({ src, size = 'md',}: { src: string size?: 'sm' | 'md' | 'lg'}) { const sizeClass = { sm: 'size-8', // 32px md: 'size-10', // 40px lg: 'size-14', // 56px }[size]
return ( <img src={src} alt="Avatar" className={`${sizeClass} rounded-full object-cover`} /> )}
function IconButton({ icon, onClick,}: { icon: React.ReactNode onClick: () => void}) { return ( <button onClick={onClick} className="size-10 flex items-center justify-center rounded-lg hover:bg-gray-100" > {icon} </button> )}任意值语法#
当预设值不满足需求时,使用方括号语法:
<!-- 任意间距 --><div class="p-[13px]">13px 内边距</div><div class="m-[2.5rem]">2.5rem 外边距</div>
<!-- 任意尺寸 --><div class="w-[calc(100%-2rem)]">计算宽度</div><div class="h-[clamp(200px,50vh,600px)]">clamp 高度</div>
<!-- CSS 变量 --><div class="p-[var(--custom-spacing)]">使用 CSS 变量</div>实战:间距的最佳实践#
8px 节奏#
保持间距为 8px 的倍数,视觉上更和谐:
function PricingCard() { return ( <div className="p-8 bg-white rounded-2xl shadow-lg"> {/* 标题区域:大间距分隔 */} <div className="mb-8"> <h3 className="text-2xl font-bold mb-2">专业版</h3> <p className="text-gray-600">适合中小团队</p> </div>
{/* 价格:醒目展示 */} <div className="mb-8"> <span className="text-5xl font-bold">¥99</span> <span className="text-gray-500">/月</span> </div>
{/* 功能列表:紧凑间距 */} <ul className="space-y-4 mb-8"> <li className="flex items-center gap-3"> <span className="size-5 rounded-full bg-green-100 text-green-600 flex items-center justify-center text-sm"> ✓ </span> <span>无限项目</span> </li> <li className="flex items-center gap-3"> <span className="size-5 rounded-full bg-green-100 text-green-600 flex items-center justify-center text-sm"> ✓ </span> <span>10GB 存储</span> </li> <li className="flex items-center gap-3"> <span className="size-5 rounded-full bg-green-100 text-green-600 flex items-center justify-center text-sm"> ✓ </span> <span>优先支持</span> </li> </ul>
{/* 操作按钮 */} <button className="w-full py-4 bg-blue-500 text-white font-medium rounded-xl hover:bg-blue-600 transition-colors"> 立即购买 </button> </div> )}间距层级#
建立清晰的间距层级:
function BlogPost() { return ( <article className="max-w-2xl mx-auto px-4"> {/* 文章头部:与正文大间距 */} <header className="mb-12"> <h1 className="text-4xl font-bold mb-4">文章标题</h1> <div className="flex items-center gap-4 text-gray-600"> <span>2025-01-15</span> <span>·</span> <span>5 分钟阅读</span> </div> </header>
{/* 正文段落:中等间距 */} <div className="space-y-6 text-lg leading-relaxed text-gray-800"> <p>段落内容...</p>
{/* 小标题与段落:较小间距 */} <h2 className="text-2xl font-bold mt-12 mb-4">章节标题</h2> <p>章节内容...</p> </div> </article> )}组件间距封装#
将常用间距模式封装为组件:
// 垂直堆叠容器function Stack({ gap = 4, children,}: { gap?: number children: React.ReactNode}) { return <div className={`flex flex-col gap-${gap}`}>{children}</div>}
// 内容容器function Container({ size = 'default', children,}: { size?: 'narrow' | 'default' | 'wide' children: React.ReactNode}) { const maxWidth = { narrow: 'max-w-2xl', default: 'max-w-4xl', wide: 'max-w-6xl', }[size]
return ( <div className={`${maxWidth} mx-auto px-4 sm:px-6 lg:px-8`}>{children}</div> )}
// 区块分隔function Section({ children }: { children: React.ReactNode }) { return <section className="py-16 sm:py-24">{children}</section>}v4 主题配置#
在 CSS 中自定义间距比例:
@import 'tailwindcss';
@theme { /* 添加自定义间距 */ --spacing-18: 4.5rem; /* 72px */ --spacing-22: 5.5rem; /* 88px */ --spacing-128: 32rem; /* 512px */
/* 自定义最大宽度 */ --max-width-8xl: 88rem; --max-width-prose: 65ch;}配置后即可使用:
<div class="p-18">自定义 72px 内边距</div><div class="max-w-prose">最大 65 字符宽度</div>间距系统是构建视觉层次的基础工具。掌握了这套比例系统,你就能快速构建出节奏感良好的界面。下一篇文章将探讨颜色与主题系统,了解 v4 的 oklch 色彩空间和暗色模式实现。