变量与模式
令牌查找、依赖项交付、inline 替换、继承和模式启用。
本页内容
主题令牌有两个角色:名称让已注册的工具类族可以使用某个值,输出的自定义属性则参与原生 CSS。Master CSS 负责解析类并保留依赖项,浏览器则通过层叠与继承解析自定义属性的值。
本页定义令牌查找、依赖项交付、替换和模式启用。主题说明何时应共享令牌,以及如何创建项目主题;令牌索引则列出预设值。
注册与查找
在顶层 @theme 块声明令牌。声明在 @theme 外的原生自定义属性可用于 CSS,但本身不会注册令牌驱动的类。原生选择器与查询应放在块外。样式表语法见 @theme。
令牌族决定要查找哪个命名空间。键是令牌名称剩余的部分,键内的连字符会保留。
| 令牌 | 类 | 生成声明 |
|---|---|---|
--spacing-card | p-card | padding: var(--spacing-card) |
--radius-card | r-card | border-radius: var(--radius-card) |
--color-brand | bg-brand | background-color: var(--color-brand) |
--color-text-action | fg-text-action | color: var(--color-text-action) |
--color-line-divider | b-line-divider | border-color: var(--color-line-divider) |
text-action 和 line-divider 都是 color 命名空间中的键。outline-line-divider 可以使用 --color-line-divider,但 outline-divider 不会自动插入 line-。两个命名空间中的同一个键可以提供不同值:p-card 和 r-card 分别解析。
@theme { --spacing-card: 1.5rem; --radius-card: .5rem; --color-brand: #1d4ed8; --color-text-action: var(--color-brand); --color-line-divider: rgb(0 0 0 / 12%);}<article class="p-card r-card b(1) b-solid b-line-divider"> <a class="fg-text-action" href="/settings">Settings</a></article>生成的 CSS
@layer theme { :root, :host { --color-line-divider: light-dark(oklch(0% 0 none / .12), oklch(100% 0 none / .12)) } :root, :host { --spacing-card: 1.5rem; --radius-card: .5rem; --color-brand: #1d4ed8; --color-text-action: var(--color-brand); --color-line-divider: #0000001f }}@layer utilities { .b-line-divider { border-color: var(--color-line-divider) } .r-card { border-radius: var(--radius-card) } .b-solid { border-style: solid } .b\(1\) { border-width: calc(1 * 1px) } .fg-text-action { color: var(--color-text-action) } .p-card { padding: var(--spacing-card) }}族索引提供完整的前缀与命名空间映射。完整 CSS 属性名称不会自动创建令牌族。项目需要新映射时,请用 @utility 注册自定义模式。即使存在同键令牌,w-full 这类固定拼写仍保留固定定义;见类解析。
原生变量不会注册令牌类
两个示例都加载预设工具类族。注册与浏览器变量可用性是两种独立能力。
文字说明
- @theme { --spacing-card: 1.5rem; } 在 spacing 命名空间注册 card 键,使 p-card 可用。
- :root { --spacing-card: 1.5rem; } 提供原生 CSS 变量,但不会注册 p-card。
- 显式原生类 (padding:var(--spacing-card)) 可以使用任一配置提供的变量。
依赖项交付
生成声明通常保留 var() 引用。被使用的受管理令牌会与其传递依赖的受管理令牌一起,输出到 theme 层的 :root, :host 下。
@theme { --spacing-card: 1.5rem;}<div class="p-card">Example</div>生成的 CSS
@layer theme { :root, :host { --spacing-card: 1.5rem }}@layer utilities { .p-card { padding: var(--spacing-card) }}令牌被保留时,其重复声明仍按源顺序保留,这些值引用的依赖项也会保留。原生样式表的引用可以保留受管理令牌;原生自定义属性声明与局部覆盖仍属于原本的样式表,并遵循该文件的保留策略。
Master CSS 生成类时不会选择浅色、深色或特定视口的值。检查功能可以报告原始声明与依赖项;没有元素、祖先与浏览器环境,就无法确定计算值。
使用令牌会一并保留其依赖项
箭头表示“引用”,不是执行顺序或层叠优先级。此例没有 static 令牌、安全列表或其他引用方。
文字说明
- 主题定义 --color-action: var(--color-brand)、--color-brand: #175cff,以及不相关的 --color-unused。
- 使用 fg-action 会在 theme 层保留 --color-action,以及其传递依赖项 --color-brand。
- 此例中,不相关的令牌没有使用根,因此不会输出。生成的 color 声明保留 var(--color-action),其值由浏览器解析。
缺失名称与无效值
未知令牌键无法生成匹配的令牌族类。这与合法类输出的 var() 后来在浏览器中解析为无效值不同。继承、循环、回退值和属性值合法性均遵循原生自定义属性规则;保留声明不代表最终计算值一定合法。
继承与限定作用域的别名
用原生选择器声明局部覆盖,相同类就能在不同作用域获得不同值:
@theme { --color-panel: white;}[data-theme="ocean"] { --color-panel: #082f49;}<section data-theme="ocean"> <div class="bg-panel">Ocean panel</div></section>派生值
--color-link: var(--color-brand) 这类别名先在声明该别名的元素上解析,再继承计算值。仅在后代元素覆盖 --color-brand,不会重新绑定已继承的别名。如果别名应由局部 brand 派生,请在后代作用域重新声明它。
相同作用域规则也适用于 color-mix() 这类派生表达式:
@theme { --color-brand: #1d4ed8; --color-link: var(--color-brand); --color-link-hover: color-mix(in oklab, var(--color-brand), black 15%);}[data-theme="plum"] { --color-brand: #86198f; --color-link: var(--color-brand); --color-link-hover: color-mix(in oklab, var(--color-brand), black 15%);}这些函数仍是 CSS 表达式。Master CSS 不会为每个编写的作用域分别计算颜色。交互别名示例会并排显示继承与重新绑定的结果。
Inline 替换与 static 交付
inline 改变生成声明引用的内容。static 改变令牌的自定义属性声明是否需要被发现的引用方。这两种行为相互独立。
| 定义 | 生成的类声明 | 自定义属性交付 |
|---|---|---|
@theme | 保留令牌引用 | 需要时保留 |
@theme inline | 将令牌值替换一次 | 替换后的类本身不再需要该令牌声明 |
@theme static | 保留令牌引用 | 即使未发现引用方也保留 |
@theme static inline | 将令牌值替换一次 | 即使未发现引用方也保留 |
Inline 替换会移除一层间接引用。替换值内的引用仍由浏览器解析,inline 不会递归地将它们替换为常量。它适用于 Master 生成的声明,包括 @apply 展开;手写原生 CSS 保留原有的 var() 引用。
剩余变量在哪里解析
以下两份配置都定义 --color-brand: var(--app-brand) 并使用 bg-brand,只有 inline 修饰符不同。两种情况下,文档根元素都是蓝色,嵌套 section 将 --app-brand 覆盖为紫红色。
Inline 替换改变剩余引用
两个示例在相同标记中使用 bg-brand。普通令牌继承根元素解析后的值;inline 则让生成声明在应用样式的元素上读取 --app-brand。
文字说明
- 两份配置都定义 --color-brand: var(--app-brand)。根元素将 --app-brand 设为 #1d4ed8,嵌套 section 则覆盖为 #86198f。
- 使用普通 @theme 时,bg-brand 输出 background-color: var(--color-brand)。根元素将 --color-brand 计算为蓝色,嵌套引用方继承该计算值。
- 使用 @theme inline 时,bg-brand 输出 background-color: var(--app-brand)。使用它的元素读取从 section 继承的紫红色值。
- 色样显示最终背景结果。图中的根元素值是计算值,并不表示编译器会计算颜色。
使用普通 @theme 时,生成声明读取 --color-brand。该令牌的 var(--app-brand) 在根元素解析,嵌套元素继承最终得到的蓝色值。
@theme { --color-brand: var(--app-brand);}:root { --app-brand: #1d4ed8;}[data-theme="plum"] { --app-brand: #86198f;}<section data-theme="plum"> <div class="bg-brand">Inherited blue</div></section>生成的 CSS
:root { --app-brand: #1d4ed8;}[data-theme="plum"] { --app-brand: #86198f;}@layer theme { :root, :host { --color-brand: var(--app-brand) }}@layer utilities { .bg-brand { background-color: var(--color-brand) }}使用 @theme inline 时,生成声明直接在应用样式的元素上读取 --app-brand,获得其 section 提供的紫红色值。
@theme inline { --color-brand: var(--app-brand);}:root { --app-brand: #1d4ed8;}[data-theme="plum"] { --app-brand: #86198f;}<section data-theme="plum"> <div class="bg-brand">Local plum</div></section>生成的 CSS
:root { --app-brand: #1d4ed8;}[data-theme="plum"] { --app-brand: #86198f;}@layer utilities { .bg-brand { background-color: var(--app-brand) }}外部引用方需要发现流程看不到的令牌时,可独立使用 static。支持的形式与定义作用域见主题修饰符。
模式启用
模式是编写的 CSS 作用域或条件,不是第二个令牌命名空间。更改令牌值与将规则限制于某个模式,是独立操作。
| 机制 | 改变的内容 | 启用条件 |
|---|---|---|
| 原生自定义属性覆盖 | 该作用域中继承的值 | 编写的选择器或原生查询 |
light-dark() 令牌 | 选取的颜色值 | 元素实际使用的配色方案 |
预设 @dark 或 @light 后缀 | 规则是否可应用 | 系统 prefers-color-scheme 媒体查询 |
通过 @apply(--name) 使用的选择器混入 | 生成规则在哪里匹配 | 与混入中编写的选择器完全一致 |
手动作用域与规则包裹
bg-surface 这类令牌类跟随其继承的变量。若只想在 ocean 作用域应用其他声明,请在混入中明确编写该作用域。& 表示生成的选择器,下方后代分支是有意编写的,不是 Master CSS 插入的。
@theme { --color-surface: white;}[data-theme="ocean"] { --color-surface: #082f49;}@mixin --ocean { &:where([data-theme="ocean"], [data-theme="ocean"] *) { @contents; }}<section data-theme="ocean"> <div class="bg-surface p(16)@apply(--ocean)">Ocean panel</div></section>生成的 CSS
[data-theme="ocean"] { --color-surface: #082f49;}@layer theme { :root, :host { --color-surface: white }}@layer utilities { .p\(16\)\@apply\(--ocean\):where([data-theme="ocean"], [data-theme="ocean"] *) { padding: calc(16 * 1px) } .bg-surface { background-color: var(--color-surface) }}令牌覆盖改变背景值,混入改变内边距应用的位置,两种机制都不会定义另一种。包裹参数与放置方式见工具类与混入。
系统偏好与手动配色方案
完整预设提供原生 color-scheme 规则:根元素允许 light dark,data-theme="light" 或 data-theme="dark" 则将区域固定为指定配色方案。令牌可用 light-dark(white, #111827) 跟随该方案。由浏览器选择值,不需要第二个类。原生行为见 light-dark()。
即使位于手动主题区域,预设的 @dark 和 @light 后缀仍是系统媒体查询。更改 data-theme 不会启用它们。颜色会演示手动启用与嵌套区域。
局部重叠与 Shadow DOM
重叠作用域遵循普通层叠,包括层顺序与选择器优先级。选择器描述了主题,并不代表局部值就自动具有更高优先级。见层叠层。
默认主题声明包含 :host。请明确编写限定作用域的 host 覆盖,并在 shadow tree 中加载所需样式表:
@theme { --color-panel: white;}:host([data-theme="dark"]) { --color-panel: #111827;}




