Skip to content

间距与尺寸系统

TailwindCSS 的间距系统建立在一套精心设计的比例之上。这套系统以 4px 为基准单位,通过倍数关系构建出和谐的视觉节奏。理解这套系统,是写出优雅 Tailwind 代码的关键。

间距比例系统#

Tailwind 默认的间距比例基于 4px(0.25rem),这是一套经过验证的设计系统:

类名后缀像素值常用场景
000px清除间距
10.25rem4px紧凑间距
20.5rem8px小间距
41rem16px标准间距
61.5rem24px组件内间距
82rem32px区块间距
123rem48px大区块间距
164rem64px区域分隔
246rem96px主要区块

完整比例: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>

类名规则:

逻辑属性#

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-xspace-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 的优势:

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 色彩空间和暗色模式实现。