@theme指令与设计令牌
本教程共 50 篇 · 第 39 篇 · 更新于 2026-07-29 · 约 8 分钟阅读
39. @theme 指令与设计令牌
本节目标:理解 Tailwind CSS v4 的设计令牌系统,掌握
@theme指令的用法,学会通过 CSS 变量定义和定制项目的主题。
v4 最大的变化之一,就是把主题配置从 JavaScript 搬到了 CSS。@theme 就是这个新系统的入口。
什么是设计令牌
设计令牌(Design Token)就是设计系统的”原子”——颜色、字体、间距、断点这些最底层的决策。在 Tailwind 里,它们以 CSS 变量的形式存在,通过 @theme 定义。
@import "tailwindcss";
@theme {
--color-mint-500: oklch(0.72 0.11 178);
--font-display: "Satoshi", sans-serif;
--breakpoint-3xl: 120rem;
}
定义 --color-mint-500 后,你就可以在 HTML 中使用 bg-mint-500、text-mint-500、fill-mint-500 等工具类。
@theme vs :root
你可能会问:为什么不直接用 :root 定义 CSS 变量?
区别在于:@theme 定义的变量会自动生成对应的工具类,而 :root 定义的变量只是普通的 CSS 变量。
/* @theme:定义后自动生成工具类 */
@theme {
--color-brand: oklch(0.72 0.11 178);
}
/* 现在可以使用 bg-brand、text-brand、border-brand 等 */
/* :root:只是普通 CSS 变量,不会生成工具类 */
:root {
--my-spacing: 2rem;
}
/* 只能用 var(--my-spacing) 引用,没有 p-[--my-spacing] 这样的工具类 */
Tip用
@theme定义需要映射到工具类的值,用:root定义纯引用的 CSS 变量。
主题变量命名空间
Tailwind 通过变量名前缀决定生成哪些工具类。每个前缀对应一个命名空间:
| 命名空间 | 生成的工具类 |
|---|---|
--color-* | bg-*、text-*、border-*、fill-* 等颜色工具类 |
--font-* | font-* 字体族工具类 |
--text-* | text-* 字体大小工具类 |
--font-weight-* | font-* 字重工具类 |
--tracking-* | tracking-* 字间距工具类 |
--leading-* | leading-* 行高工具类 |
--breakpoint-* | sm:*、md:* 等响应式变体 |
--container-* | @sm:* 等容器查询变体 |
--spacing-* | p-*、m-*、gap-* 等间距工具类 |
--radius-* | rounded-* 圆角工具类 |
--shadow-* | shadow-* 阴影工具类 |
--blur-* | blur-* 模糊工具类 |
--ease-* | ease-* 缓动函数工具类 |
--animate-* | animate-* 动画工具类 |
扩展默认主题
在默认主题基础上添加新值,不会覆盖已有定义:
@import "tailwindcss";
@theme {
/* 添加新字体 */
--font-script: "Great Vibes", cursive;
/* 添加新颜色 */
--color-avocado-100: oklch(0.99 0 0);
--color-avocado-200: oklch(0.98 0.04 113.22);
--color-avocado-300: oklch(0.94 0.11 115.03);
--color-avocado-400: oklch(0.92 0.19 114.08);
--color-avocado-500: oklch(0.84 0.18 117.33);
--color-avocado-600: oklch(0.53 0.12 118.34);
/* 添加新断点 */
--breakpoint-3xl: 120rem;
/* 添加新缓动函数 */
--ease-fluid: cubic-bezier(0.3, 0, 0, 1);
--ease-snappy: cubic-bezier(0.2, 0, 0, 1);
}
现在可以使用 font-script、bg-avocado-300、3xl:grid-cols-6、ease-fluid 等新工具类。
覆盖默认主题
重新定义已有的变量值,会替换默认行为:
@import "tailwindcss";
@theme {
/* 覆盖默认 sm 断点 */
--breakpoint-sm: 30rem; /* 原来是 40rem */
/* 覆盖默认字体 */
--font-sans: "Inter", sans-serif;
}
完全自定义主题
如果想从零开始,禁用所有默认值:
@import "tailwindcss";
@theme {
--*: initial; /* 禁用所有默认主题变量 */
/* 只定义你需要的 */
--spacing: 4px;
--font-body: "Inter", sans-serif;
--color-lagoon: oklch(0.72 0.11 221.19);
--color-coral: oklch(0.74 0.17 40.24);
--color-driftwood: oklch(0.79 0.06 74.59);
--color-tide: oklch(0.49 0.08 205.88);
--color-dusk: oklch(0.82 0.15 72.09);
}
Warning
--*: initial会移除所有默认工具类(如bg-red-500、font-serif),只保留你自定义的。使用前确认这是你想要的。
也可以只禁用某个命名空间:
@theme {
--color-*: initial; /* 只禁用颜色相关的默认工具类 */
--color-white: #fff;
--color-purple: #3f3cbb;
--color-midnight: #121063;
}
定义动画关键帧
在 @theme 中定义 --animate-* 变量时,可以同时定义对应的 @keyframes:
@theme {
--animate-fade-in-scale: fade-in-scale 0.3s ease-out;
@keyframes fade-in-scale {
0% {
opacity: 0;
transform: scale(0.95);
}
100% {
opacity: 1;
transform: scale(1);
}
}
}
<div class="animate-fade-in-scale">淡入并放大</div>
引用其他变量
当主题变量需要引用其他变量时,使用 inline 选项:
@theme inline {
--font-sans: var(--font-inter);
}
inline 会让工具类直接使用变量的值,而不是引用变量本身。这在变量来自外部(如设计工具导出)时很有用。
/* 不使用 inline:工具类引用 --font-sans */
.font-sans { font-family: var(--font-sans); }
/* 使用 inline:工具类直接使用 --font-inter 的值 */
.font-sans { font-family: var(--font-inter); }
使用主题变量
定义好的主题变量,可以在自定义 CSS 中直接引用:
@layer components {
.typography {
p {
font-size: var(--text-base);
color: var(--color-gray-700);
}
h1 {
font-size: var(--text-2xl);
font-weight: var(--font-weight-semibold);
}
}
}
也可以在 HTML 的任意值中使用:
<div class="rounded-[calc(var(--radius-xl)-1px)]">
嵌套元素的内边框半径
</div>
跨项目共享主题
主题变量定义在 CSS 里,所以共享主题就是共享一个 CSS 文件:
/* packages/brand/theme.css */
@theme {
--*: initial;
--spacing: 4px;
--font-body: "Inter", sans-serif;
--color-lagoon: oklch(0.72 0.11 221.19);
--color-coral: oklch(0.74 0.17 40.24);
}
/* packages/admin/app.css */
@import "tailwindcss";
@import "../brand/theme.css";
Tip把主题变量抽成独立的 CSS 文件,可以在 monorepo 中多个项目共享,也可以发布到 NPM 供团队使用。
@theme 是 v4 主题系统的基石。把它吃透,你就能随心所欲地定制 Tailwind。