主题与自定义
Tailwind 的主题是一组扁平的 CSS 变量。你可以通过输入 CSS 中的 @theme { … } 块来扩展或替换它,通过主题函数在 CSS 中引用这些值,并从 PHP 读取解析后的值。这里没有 JavaScript 配置文件——主题完全位于 CSS 中。
@theme 块
@theme 块会将设计令牌声明为 CSS 自定义属性。每个变量的命名空间前缀(--color-*、--font-*、--breakpoint-*、--spacing-*、……)会告知 Tailwind 该令牌对应哪些实用工具和变体。
use TailwindPHP\tw;
$css = tw::generate('<div class="bg-brand text-brand xs:flex">', '
@import "tailwindcss";
@theme {
--color-brand: #3b82f6;
--font-heading: "Inter", sans-serif;
--breakpoint-xs: 20rem;
--spacing-huge: 10rem;
}
');
每个令牌都会在其命名空间下注册实用工具。上面的示例会提供 bg-brand、text-brand、border-brand、font-heading 系列、xs: 响应式变体,以及 p-huge/m-huge 间距——只有当类名出现在你的内容中时才会生成。
/* bg-brand resolves to the theme variable */
:root, :host {
--color-brand: #3b82f6;
}
.bg-brand {
background-color: var(--color-brand);
}
--breakpoint-xs 令牌会直接注册 xs: 变体:
@media (min-width: 20rem) {
.xs\:flex {
display: flex;
}
}
常见命名空间
| 命名空间 | 对应项 |
|---|---|
--color-* |
bg-*、text-*、border-*、fill-*、stroke-*、…… |
--font-* |
font-* 系列实用工具 |
--text-* |
text-* 字号实用工具 |
--breakpoint-* |
响应式变体(sm:、md:、自定义 xs:) |
--spacing-* |
命名间距值(p-huge、m-huge) |
--radius-* |
rounded-* 实用工具 |
--shadow-* |
shadow-* 实用工具 |
清除命名空间
将命名空间通配符设为 initial,会在添加你自己的令牌之前移除 Tailwind 在该命名空间中的默认值。这样你就可以从空白调色板开始:
@theme {
/* Drop every default color, then define only what you need */
--color-*: initial;
--color-brand: #3b82f6;
--color-ink: #111827;
}
--*: initial; 会清除整个主题。对于非通配符键(--color-red-500: initial;),单个 initial 值只会移除该令牌。-* 通配符的值只能是 initial,其他任何值都会报错。
在 CSS 中读取主题值
theme()
旧版 theme() 函数使用点号表示法,根据 v3 风格的命名空间读取值。它会在编译时解析为令牌的值,因此可用于任何需要值的位置,包括自定义规则和其他声明。
$css = tw::generate('<div class="callout">', '
@import "tailwindcss";
.callout { color: theme(colors.red.500); }
');
.callout {
color: oklch(63.7% .237 25.331);
}
点号路径会映射到底层变量(colors.red.500 → --color-red-500,fontFamily.sans → 无衬线字体系列)。支持不透明度修饰符:theme(colors.red.500 / 50%)。也可以通过第二个参数传入回退值:theme(colors.brand, #000)。如果路径无法解析且未提供回退值,使用它的候选项就会被丢弃。
--theme()
--theme() 根据 CSS 自定义属性名称读取主题变量,默认返回 var() 引用,因此该值在运行时仍可覆盖:
.btn { color: --theme(--color-brand); }
/* → color: var(--color-brand); */
添加 inline 可用解析后的值替代 var() 引用:--theme(--color-brand inline)。第二个参数是回退值(--theme(--color-brand, #000));initial 回退值会特殊处理——注入到嵌套的 var() 引用中,这些引用本身会解析为 initial。在 at-rule(@media、@container)内部,--theme() 始终会内联解析,因为 var() 在这些前导部分中无效。
--spacing()
--spacing(n) 将主题的基础间距单位(--spacing)乘以 n:
@utility my-gap { gap: --spacing(4); }
/* → gap: calc(var(--spacing) * 4); */
乘数为 1 时会解析为基础变量本身(--spacing(1) → var(--spacing),这也是 p-1 输出的内容);0 则会解析为纯零长度。
这与内置间距实用工具使用的计算方式相同,因此自定义值与 p-4、m-4 等保持一致。
--alpha()
--alpha(color / opacity) 使用 oklab 色彩空间中的 color-mix() 对颜色应用不透明度:
@utility tint { color: --alpha(var(--color-red-500) / 50%); }
.tint {
color: #fb2c3680;
}
@supports (color: color-mix(in lab, red, red)) {
.tint {
color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
}
}
color-mix() 形式在运行时仍可覆盖;它前面的静态回退值根据主题值计算,可供不支持 color-mix() 的浏览器使用。通过 polyfills 选项关闭回退:tw::compile()。
叠加不透明度与 color-mix() → oklab()
不透明度修饰符可以叠加。对已有 50% 不透明度的值再应用 50%,结果就是 25%,并在 oklab 中计算。当不透明度修饰符针对静态颜色解析时,TailwindPHP 会将 color-mix(in oklab, …) 表达式折叠为具体的 oklab() 值——这与上游 Tailwind 工具链中 lightningcss 执行的转换相同;而动态颜色(仍由 var() 包裹的颜色)会保留 color-mix() 形式,因此仍可在运行时覆盖。
从 PHP 读取主题值
三个访问器会将解析后的主题值作为 PHP 数组返回。每个访问器都接受可选的输入 CSS 字符串(默认为 @import "tailwindcss";),也可通过 compiler instance 使用。
use TailwindPHP\tw;
tw::colors();
// ['red-500' => 'oklch(63.7% .237 25.331)', 'blue-500' => 'oklch(62.3% .214 259.815)', ...]
tw::breakpoints();
// ['sm' => '40rem', 'md' => '48rem', 'lg' => '64rem', 'xl' => '80rem', '2xl' => '96rem']
tw::spacing('@import "tailwindcss"; @theme { --spacing-huge: 10rem; }');
// ['huge' => '10rem']
传入 CSS 字符串,即可根据自定义主题读取:
tw::colors('@import "tailwindcss"; @theme { --color-brand: #3b82f6; }');
// [..., 'brand' => '#3b82f6']
tw::breakpoints('@import "tailwindcss"; @theme { --breakpoint-xs: 20rem; }');
// ['sm' => '40rem', ..., '2xl' => '96rem', 'xs' => '20rem']
TailwindCSS 4 使用单个 --spacing 基础值,而不是 --spacing-* 刻度,因此 tw::spacing() 只会返回你定义的自定义 --spacing-* 令牌。从编译器实例调用时也有相同的方法:$compiler->colors()、$compiler->breakpoints()、$compiler->spacing()。完整签名请参阅 参考API。