跳转到正文

主题与自定义

Tailwind 的主题是一组扁平的 CSS 变量。你可以通过输入 CSS 中的 @theme { … } 块来扩展或替换它,通过主题函数在 CSS 中引用这些值,并从 PHP 读取解析后的值。这里没有 JavaScript 配置文件——主题完全位于 CSS 中。

@theme 块

@theme 块会将设计令牌声明为 CSS 自定义属性。每个变量的命名空间前缀(--color-*、--font-*、--breakpoint-*、--spacing-*、……)会告知 Tailwind 该令牌对应哪些实用工具和变体。

PHP
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 间距——只有当类名出现在你的内容中时才会生成。

CSS
/* bg-brand resolves to the theme variable */
:root, :host {
  --color-brand: #3b82f6;
}
.bg-brand {
  background-color: var(--color-brand);
}

--breakpoint-xs 令牌会直接注册 xs: 变体:

CSS
@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 在该命名空间中的默认值。这样你就可以从空白调色板开始:

CSS
@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 风格的命名空间读取值。它会在编译时解析为令牌的值,因此可用于任何需要值的位置,包括自定义规则和其他声明。

PHP
$css = tw::generate('<div class="callout">', '
    @import "tailwindcss";
    .callout { color: theme(colors.red.500); }
');
CSS
.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() 引用,因此该值在运行时仍可覆盖:

CSS
.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:

CSS
@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() 对颜色应用不透明度:

CSS
@utility tint { color: --alpha(var(--color-red-500) / 50%); }
CSS
.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 使用。

PHP
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 字符串,即可根据自定义主题读取:

PHP
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。

后续步骤

  • 指令 — @apply、@utility、@custom-variant、@layer。
  • 导入 — @import、虚拟模块和 Preflight。
  • API — 所有访问器和检查方法。