一、间距概述
1. 什么是间距刻度
作用说明: Tailwind 的间距刻度,就是一套用来统一控制"距离"的数值体系。内边距、外边距、子元素间距、宽高都共用这套刻度,因此整个页面看起来会比较协调,不会出现一个地方用 14px、另一个地方又用 15px 的零散情况。
这套刻度由 --spacing 这个 CSS 变量驱动,默认值是 0.25rem,也就是 4px。写类名时,数字会乘以这个基础值得到最终距离。例如 p-4 就是 4 × 0.25rem = 1rem,也就是 16px。
| 类名中的数字 | 实际间距 | 换算成像素 | 常见用途 |
|---|---|---|---|
0.5 |
0.125rem | 2px | 极小的间隙 |
1 |
0.25rem | 4px | 图标与文字的紧贴间距 |
2 |
0.5rem | 8px | 标签、小按钮内部间距 |
3 |
0.75rem | 12px | 表单、紧凑卡片 |
4 |
1rem | 16px | 最常见的卡片内边距 |
6 |
1.5rem | 24px | 段落间距、区块间距 |
8 |
2rem | 32px | 较大的区块间隔 |
12 |
3rem | 48px | 大区块之间的留白 |
16 |
4rem | 64px | 页面级留白 |
html
<!-- 同一个间距刻度可以用在不同属性上,视觉节奏一致 -->
<div class="space-y-4 p-4">
<button class="rounded-lg bg-blue-600 px-4 py-2 text-white">按钮</button>
<p class="text-gray-700">这段文字与按钮之间的间距同样来自刻度里的 4。</p>
</div>
除了数字,还有一个特殊值 px,它不受基础刻度影响,固定表示 1px:
html
<div class="border border-gray-300 p-px">内边距固定为 1px。</div>
2. 动态间距刻度说明
作用说明: Tailwind CSS v3 的间距刻度是"写死"的一串数字,通常只有 0、0.5、1、1.5、2、2.5、3、3.5、4 等有限档位。而 v4 改成了动态刻度,只要在 --spacing 基础上,任意数字都能直接生成对应的工具类。
也就是说,p-17、m-13、gap-23 这类 v3 里不存在的写法,在 v4 中都能正常使用,它们分别等于 17 × 0.25rem、13 × 0.25rem、23 × 0.25rem。
html
<!-- v4 中可以直接使用任意数字,不需要提前定义 -->
<div class="p-17">
<div class="flex gap-23">
<span>项目一</span>
<span>项目二</span>
</div>
</div>
如果想整体改变间距体系,只需要在 @theme 里修改 --spacing。例如把基础值改为 0.2rem,所有间距工具都会同步缩放:
css
@import "tailwindcss";
@theme {
/* 默认 0.25rem,这里改成 0.2rem(8px 体系中的 1 档) */
--spacing: 0.2rem;
}
修改后,p-4 就不再是 16px,而是 4 × 0.2rem = 0.8rem,也就是 12.8px。
使用指南: 动态刻度让数值更自由,但一个项目里仍然建议统一使用 4px 或 8px 体系的整数,避免到处出现奇怪的小数。0.5、1.5 这类半档只在小图标、紧密元素里偶尔使用。
避坑指南: 任意值写法 p-[13px] 是直接写具体像素,它不参与 --spacing 的缩放。如果以后修改了 --spacing,p-13 会跟着变,而 p-[13px] 不会,两者不要混淆。
二、内边距(padding)
1. 四边与单边写法(p / px / py / pt / pr / pb / pl)
作用说明: 内边距是元素内容与边框之间的距离,简单说就是"让内容不要贴着边缘"。Tailwind 用 p-* 表示四边内边距,用 pt-*、pr-*、pb-*、pl-* 分别表示上、右、下、左四个方向,px-* 和 py-* 则同时控制水平或垂直方向。
| 类名 | 控制范围 |
|---|---|
p-* |
上下左右四边 |
px-* |
左边 + 右边(水平方向) |
py-* |
上边 + 下边(垂直方向) |
pt-* |
只有上边 |
pr-* |
只有右边 |
pb-* |
只有下边 |
pl-* |
只有左边 |
html
<!-- 卡片:四周留白 + 上下方向留白 -->
<article class="rounded-xl bg-white p-6 shadow-sm">
<h2 class="text-lg font-semibold text-gray-900">卡片标题</h2>
<p class="mt-2 text-sm text-gray-600">这里使用 p-6 给四周都留出 24px 的内边距。</p>
</article>
html
<!-- 按钮:水平留白比垂直留白大,形成常见按钮比例 -->
<button class="rounded-lg bg-blue-600 px-6 py-2 text-sm font-medium text-white">
立即注册
</button>
也可以按需要叠加单边写法,后面写的类会覆盖前面写过的同一边:
html
<div class="p-4 pb-8">四边 16px,但底部覆盖为 32px。</div>
和所有间距工具一样,内边距支持任意值:
html
<div class="p-[18px]">使用精确的 18px 内边距。</div>
适用场景: 卡片、按钮、输入框、导航、表格单元格等几乎所有需要"留出内容呼吸空间"的容器。
2. 逻辑属性(ps / pe)
作用说明: ps-* 和 pe-* 是内边距的逻辑属性写法。ps 表示 padding-inline-start,也就是文字开始的一侧;pe 表示 padding-inline-end,也就是文字结束的一侧。
在从左到右的语言中,ps 等价于左边 pl,pe 等价于右边 pr;但如果页面切换成从右到左的语言,ps 会自动变成右边,pe 会自动变成左边。
| 类名 | 对应 CSS 属性 | 左到右语言中的效果 |
|---|---|---|
ps-* |
padding-inline-start |
左侧内边距 |
pe-* |
padding-inline-end |
右侧内边距 |
px-* |
padding-inline |
左右同时 |
pbs-* |
padding-block-start |
上侧内边距 |
pbe-* |
padding-block-end |
下侧内边距 |
html
<!-- 在需要支持 RTL 的项目里,用 ps/pe 比 pl/pr 更稳妥 -->
<div class="ps-4 pe-8 py-2">
文字开始一侧留 16px,结束一侧留 32px。
</div>
适用场景: 多语言网站、国际化的界面组件、需要同时支持中文和阿拉伯语等双向文字的布局。
避坑指南: 如果项目只面向中文等从左到右语言,ps、pe 与 pl、pr 的效果相同,按团队习惯选择即可。但进入国际化项目时,优先使用 ps、pe、px、py 这些逻辑属性,能减少 RTL 适配工作量。
三、外边距(margin)
1. 四边与单边写法(m / mx / my / mt / mr / mb / ml)
作用说明: 外边距是元素与相邻元素之间的空白,用来拉开两个元素的间距。写法与内边距对称:m-* 四边,mt、mr、mb、ml 分别对应上、右、下、左,mx-* 和 my-* 分别控制水平和垂直。
| 类名 | 控制范围 |
|---|---|
m-* |
上下左右四边 |
mx-* |
左边 + 右边 |
my-* |
上边 + 下边 |
mt-* |
只有上边 |
mr-* |
只有右边 |
mb-* |
只有下边 |
ml-* |
只有左边 |
html
<div class="mt-4">
<p class="mb-2 text-gray-700">第一个段落,底部留出 8px。</p>
<p class="text-gray-700">第二个段落。</p>
</div>
html
<!-- 水平方向统一留白,常用于整页内容两侧 -->
<main class="mx-4 text-gray-800">
这段内容左右各有 16px 的外边距。
</main>
外边距也有逻辑属性写法:ms-* 对应 margin-inline-start,me-* 对应 margin-inline-end,mbs-*、mbe-* 分别对应块方向起止。它们的用法与内边距的 ps、pe 一致:
html
<div class="ms-4 me-8">文字开始一侧 16px,结束一侧 32px。</div>
适用场景: 段落之间的间距、标题与正文的间距、区块之间的留白。凡是元素"外部"的距离,都用 margin;元素"内部"的距离,用 padding。
2. 负值与 auto 居中
作用说明: 外边距支持负值,也支持 auto。负值可以让元素向外移动或重叠;auto 则让浏览器自动分配剩余空间,最常见的用途是水平居中。
负值: 在类名前加一个减号,例如 -mt-4 表示向上偏移 16px。
html
<!-- 让头像与上面的卡片产生一点重叠效果 -->
<div class="relative">
<div class="h-24 rounded-xl bg-blue-100"></div>
<img
class="-mt-8 ml-6 size-16 rounded-full border-4 border-white bg-gray-300"
src="/avatar.png"
alt="用户头像"
/>
</div>
auto 居中: 一个块级元素设置 mx-auto,同时有明确宽度时,就会在父容器中水平居中。
html
<!-- 内容宽度最大 28rem,并水平居中 -->
<div class="mx-auto max-w-md rounded-lg bg-white p-6">
这是一块居中的内容。
</div>
除了 mx-auto,也可以只用一侧 auto 来把元素推到另一边:
html
<div class="flex items-center">
<span>标题</span>
<button class="ms-auto rounded bg-blue-600 px-3 py-1 text-sm text-white">右侧按钮</button>
</div>
避坑指南: mx-auto 只对块级元素有效。行内元素(如 <span>)默认不占满整行,设置 mx-auto 不会居中;此时可以先把元素改成 block 或 flex 布局处理。垂直方向要居中,通常用 Flexbox 的 items-center 或 Grid 的 place-items-center,而不是简单写 my-auto。
四、子元素之间的间距
1. gap
作用说明: gap-* 用来控制 Flexbox 或 Grid 容器里子元素之间的间隔。它是现代布局中处理间距的首选,因为间距由父容器统一管理,子元素不需要各自写 margin。
| 类名 | 控制范围 |
|---|---|
gap-* |
行间距和列间距同时设置 |
gap-x-* |
只设置列间距(水平方向) |
gap-y-* |
只设置行间距(垂直方向) |
html
<!-- Flexbox 中的水平间距 -->
<div class="flex gap-4">
<button class="rounded bg-blue-600 px-3 py-2 text-white">按钮一</button>
<button class="rounded bg-blue-600 px-3 py-2 text-white">按钮二</button>
<button class="rounded bg-blue-600 px-3 py-2 text-white">按钮三</button>
</div>
html
<!-- Grid 中分别控制行距和列距 -->
<div class="grid grid-cols-3 gap-x-8 gap-y-4">
<div class="bg-gray-100 p-4">1</div>
<div class="bg-gray-100 p-4">2</div>
<div class="bg-gray-100 p-4">3</div>
<div class="bg-gray-100 p-4">4</div>
</div>
适用场景: 导航、按钮组、卡片网格、表单控件排列、标签组。只要父容器是 flex 或 grid,都可以优先使用 gap-*。
2. space-x / space-y
作用说明: space-x-* 和 space-y-* 会给"除最后一个子元素之外"的每个子元素添加外边距,从而在子元素之间形成间隔。它适合子元素排列方向明确的简单场景。
| 类名 | 方向 |
|---|---|
space-x-* |
水平方向间隔 |
space-y-* |
垂直方向间隔 |
space-x-reverse |
配合反向排列时,把间距加到正确一侧 |
space-y-reverse |
配合反向排列时,把间距加到正确一侧 |
html
<!-- 垂直排列的一排菜单项 -->
<ul class="space-y-3 text-gray-700">
<li>首页</li>
<li>产品</li>
<li>关于我们</li>
</ul>
html
<!-- 水平排列的标签组 -->
<div class="flex space-x-2">
<span class="rounded-full bg-gray-100 px-3 py-1 text-sm">标签一</span>
<span class="rounded-full bg-gray-100 px-3 py-1 text-sm">标签二</span>
<span class="rounded-full bg-gray-100 px-3 py-1 text-sm">标签三</span>
</div>
gap 和 space-* 都能制造子元素间距,但有明显区别:
| 对比项 | gap-* |
space-x-* / space-y-* |
|---|---|---|
| 作用原理 | 父容器设置 gap 属性 | 给每个非最后子元素加 margin |
| 适用布局 | Flexbox、Grid | 主要是 Flexbox 或普通流 |
| 换行处理 | 换行后仍能正确留间距 | 换行后效果会不理想 |
| 子元素自定义 | 不依赖子元素 | 子元素自带 margin,可能被覆盖 |
| 推荐程度 | 现代布局首选 | 只在简单、不换行的场景使用 |
避坑指南: 如果容器里的子元素会换行,或者使用 Grid 布局,请使用 gap-*,不要用 space-x-*、space-y-*。space-* 是给非最后子元素加 margin 的快捷方式,在网格、换行、复杂排序等场景下容易出错。
五、宽度、高度与统一尺寸
3. 宽度(width)
作用说明: w-* 用来设置元素宽度。v4 中宽度既可以使用间距刻度的数字,也可以使用百分比分数、容器尺寸、视口单位或任意值。
| 写法 | 作用 | 示例 |
|---|---|---|
w-<数字> |
按间距刻度设置固定宽度 | w-24、w-64 |
w-px |
宽度 1px | w-px |
w-full |
宽度 100% | w-full |
w-<分数> |
按父容器百分比 | w-1/2、w-2/3 |
w-auto |
浏览器自动计算 | w-auto |
w-screen |
宽度等于视口宽度 | w-screen |
w-min / w-max / w-fit |
按内容最小/最大/合适宽度 | w-fit |
w-xs 到 w-7xl |
使用容器尺寸刻度 | w-md、w-xl |
w-[<值>] |
任意宽度 | w-[320px] |
html
<!-- 固定宽度 -->
<div class="w-64 rounded-lg bg-gray-100 p-4">固定宽度 256px</div>
<!-- 占满父容器 -->
<div class="w-full rounded-lg bg-blue-100 p-4">占满父容器</div>
<!-- 内容自适应宽度 -->
<span class="w-fit rounded bg-gray-100 px-3 py-1">按钮文本</span>
容器尺寸刻度适合做固定宽度的卡片或侧边栏:
html
<aside class="w-64 rounded-xl bg-white p-4 shadow-sm">
这是一个 16rem 宽的侧边栏。
</aside>
避坑指南: w-full 是 width: 100%,它会受父元素宽度和元素自身盒模型影响。如果元素还有 px-* 内边距,默认 box-sizing: border-box 下内容会自动收缩,不会溢出;但如果父元素宽度不确定,w-full 可能不如 w-<数字> 直观。
4. 高度(height)
作用说明: h-* 用来设置元素高度。写法和宽度类似,但高度更常用 h-full、视口单位以及固定像素。
| 写法 | 作用 | 示例 |
|---|---|---|
h-<数字> |
按间距刻度设置固定高度 | h-24、h-64 |
h-px |
高度 1px | h-px |
h-full |
高度 100% | h-full |
h-<分数> |
按父容器百分比 | h-1/2 |
h-auto |
浏览器自动计算 | h-auto |
h-screen |
高度等于视口高度 | h-screen |
h-dvh / h-svh / h-lvh |
动态、小、大视口高度 | h-dvh |
h-min / h-max / h-fit |
按内容最小/最大/合适高度 | h-fit |
h-[<值>] |
任意高度 | h-[32rem] |
html
<!-- 固定高度容器 -->
<div class="h-64 w-full rounded-lg bg-gray-100 p-4">固定高度 256px</div>
html
<!-- 首屏区域占满动态视口高度,移动端浏览器工具栏收起/展开时更准确 -->
<section class="h-dvh bg-slate-900 text-white">
<div class="flex h-full items-center justify-center">
<h1 class="text-4xl font-bold">首屏标题</h1>
</div>
</section>
避坑指南: 百分比高度 h-full、h-1/2 要求父元素有确定的高度。如果父元素没有设置高度,h-full 可能不会产生预期效果,这时可以考虑给父元素设置 h-dvh、h-screen 或固定高度。
5. 统一尺寸(size)
作用说明: size-* 可以同时设置宽度和高度,非常适合需要保持正方形的元素,例如头像、图标、色块、加载圆圈。
| 写法 | 作用 |
|---|---|
size-<数字> |
宽高都为间距刻度对应值 |
size-px |
宽高都为 1px |
size-full |
宽高都为 100% |
size-<分数> |
宽高都为对应百分比 |
size-[<值>] |
宽高都为任意值 |
html
<!-- 头像:宽高都是 40px,自动成正方形 -->
<img class="size-10 rounded-full" src="/avatar.png" alt="头像" />
<!-- 图标容器 -->
<button class="flex size-10 items-center justify-center rounded-full bg-blue-50 text-blue-600">
<svg
class="size-5 fill-current"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12 2l3 6h6l-5 4 2 7-6-4-6 4 2-7-5-4h6z" />
</svg>
</button>
使用指南: 过去写正方形元素需要 h-10 w-10 两个类,v4 用 size-10 一个类即可,代码更简洁。圆形头像、彩色小方块、点赞按钮等都推荐使用 size-*。
六、最大最小尺寸与百分比
1. max-* / min-*
作用说明: max-* 限制元素"最大不能超过多少",min-* 限制元素"最小不能低于多少"。它们可以和固定尺寸、百分比、内容自适应等配合,让布局在屏幕变化时更稳健。
| 类名 | 作用 | 常见示例 |
|---|---|---|
max-w-* |
最大宽度 | max-w-md、max-w-full |
min-w-* |
最小宽度 | min-w-0、min-w-64 |
max-h-* |
最大高度 | max-h-96、max-h-screen |
min-h-* |
最小高度 | min-h-screen、min-h-0 |
html
<!-- 限制正文最大宽度,让长行更好阅读,并水平居中 -->
<article class="mx-auto max-w-2xl px-4 text-gray-800">
当屏幕很宽时,文字也不会无限拉长,仍然保持舒适的阅读宽度。
</article>
html
<!-- 列表容器有最大高度,超出后可滚动 -->
<ul class="max-h-64 overflow-y-auto rounded-lg border border-gray-200">
<li class="p-3">列表项 1</li>
<li class="p-3">列表项 2</li>
<li class="p-3">列表项 3</li>
</ul>
html
<!-- min-h-screen 保证内容不足时,页面仍然撑满整屏 -->
<main class="min-h-screen bg-gray-50 p-6">
<p>即使内容很少,背景也会铺满整个视口。</p>
</main>
避坑指南: 在 Flexbox 里,子元素默认不会缩小到内容宽度以下,长文字或长链接容易把布局撑开。此时给子元素加 min-w-0 往往能解决问题,它允许元素缩到比内容更小,配合 truncate、break-words 等处理溢出。
2. 视口单位(vw / vh / dvw / dvh)
作用说明: 视口单位根据浏览器窗口大小来设置尺寸。vw 是视口宽度的 1%,vh 是视口高度的 1%。但在手机浏览器上,工具栏的收起和展开会让"实际可见高度"变化,于是又出现了动态视口单位。
| 类名 | 对应单位 | 说明 |
|---|---|---|
w-screen |
100vw |
固定视口宽度 |
h-screen |
100vh |
固定视口高度 |
w-dvw |
100dvw |
动态视口宽度,会随浏览器 UI 变化 |
h-dvh |
100dvh |
动态视口高度,移动端最常用 |
w-svw / w-lvw |
100svw / 100lvw |
小视口宽度 / 大视口宽度 |
h-svh / h-lvh |
100svh / 100lvh |
小视口高度 / 大视口高度 |
html
<!-- 移动端首屏推荐 h-dvh,避免底部被工具栏遮住或出现跳动 -->
<section class="flex h-dvh items-center justify-center bg-slate-900 text-white">
<h1 class="text-3xl font-bold">移动端友好的首屏</h1>
</section>
html
<!-- min-h-svh 保证至少等于小视口高度,内容变多时也能自动撑开 -->
<main class="min-h-svh bg-gray-50 p-6">
内容区域至少占满一屏,同时允许往下继续增长。
</main>
使用指南: 桌面端 h-screen、w-screen 足够;移动端需要更精确控制时优先用 dvh、svh、lvh。dvh 会随着移动浏览器地址栏伸缩而变化,能减少"底部多一块空白"或"内容被遮住"的问题。
3. 百分比分数(如 1/2、1/3)
作用说明: 分数写法让元素宽度等于父容器的百分比,例如 w-1/2 是 50%,w-1/3 是约 33.33%。它比手写 w-[50%] 更直观,也方便快速搭出等分或比例布局。
| 类名 | 百分比 |
|---|---|
w-1/2 |
50% |
w-1/3 |
33.33% |
w-2/3 |
66.67% |
w-1/4 |
25% |
w-3/4 |
75% |
w-1/5 |
20% |
w-2/5 |
40% |
w-3/5 |
60% |
w-4/5 |
80% |
w-full |
100% |
html
<!-- 左右比例布局:侧栏 1/4,主内容 3/4 -->
<div class="flex gap-4">
<aside class="w-1/4 rounded-lg bg-gray-100 p-4">侧边栏</aside>
<main class="w-3/4 rounded-lg bg-white p-4 shadow-sm">主内容</main>
</div>
html
<!-- 三等分卡片 -->
<div class="flex gap-4">
<div class="w-1/3 rounded-lg bg-gray-100 p-4">第一列</div>
<div class="w-1/3 rounded-lg bg-gray-100 p-4">第二列</div>
<div class="w-1/3 rounded-lg bg-gray-100 p-4">第三列</div>
</div>
在 v4 中,分数也是动态写法,理论上任意 分子/分母 都能生成对应百分比:
html
<div class="w-[7/10] bg-blue-100 p-4">宽度为父容器的 70%。</div>
适用场景: 两栏、三栏布局,图文比例,卡片网格。需要更复杂的响应式等分布局时,通常配合 Grid 的 grid-cols-* 使用,但如果只是简单的水平比例,用 w-* 分数就很直观。
避坑指南: 多个 w-1/3 放在 Flexbox 里默认不换行,如果还设置了 gap,三个 33.33% 加起来的宽度可能超过父容器而溢出。需要等分且带间距时,优先使用 Grid 的 grid-cols-3,而不是手动写三个 w-1/3。