ナビゲーション

構文

変数とモード

トークンの検索、依存関係の配信、inline による置換、継承、モードの有効化。

このページの内容

テーマトークンには 2 つの役割があります。名前は登録済みのユーティリティファミリーに値を提供し、出力されるカスタムプロパティはネイティブ CSS に参加します。Master CSS はクラスを解決して依存関係を保持し、ブラウザーはカスケードと継承でカスタムプロパティの値を解決します。

このページは、トークンの検索、依存関係の配信、置換、モードの有効化を定義します。トークンを共有する判断とプロジェクトのテーマ作成はテーマで説明し、プリセット値はトークン索引に掲載しています。

登録と検索

トークンはトップレベルの @theme ブロックに宣言します。@theme の外のネイティブカスタムプロパティは CSS で使えますが、それだけではトークンを参照するクラスを登録しません。ネイティブセレクターとクエリーはブロックの外に置きます。スタイルシートの文法は @themeを参照してください。

トークンファミリーが検索する名前空間を決めます。キーはトークン名の残りの部分であり、キー内のハイフンは保持されます。

トークンクラス生成される宣言
--spacing-cardp-cardpadding: var(--spacing-card)
--radius-cardr-cardborder-radius: var(--radius-card)
--color-brandbg-brandbackground-color: var(--color-brand)
--color-text-actionfg-text-actioncolor: var(--color-text-action)
--color-line-dividerb-line-dividerborder-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 などの固定の綴りは、同じキーのトークンがあっても固定の定義を保ちます。クラスの解決を参照してください。

ネイティブ変数だけではトークンクラスは登録されない

どちらの例もプリセットのユーティリティファミリーを読み込みます。登録と、ブラウザーで変数が使えることは別の機能です。

テキストによる説明
  1. @theme { --spacing-card: 1.5rem; } は spacing 名前空間に card キーを登録し、p-card を利用可能にします。
  2. :root { --spacing-card: 1.5rem; } はネイティブ CSS 変数を提供しますが、p-card は登録しません。
  3. 明示的なネイティブクラス (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 トークン、セーフリスト、ほかの参照元はありません。

テキストによる説明
  1. テーマは --color-action: var(--color-brand)、--color-brand: #175cff と、無関係な --color-unused を定義します。
  2. fg-action を使うと、theme レイヤーに --color-action と、推移的に依存する --color-brand が保持されます。
  3. この例では無関係なトークンに使用の起点がないため、出力されません。生成する 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 は、トークンのカスタムプロパティ宣言に、探索で見つかる参照元が必要かどうかを変えます。この 2 つの動作は独立しています。

定義生成クラスの宣言カスタムプロパティの配信
@themeトークン参照を保持必要な場合に保持
@theme inlineトークン値を一度置換置換したクラス自体はそのトークン宣言を必要としない
@theme staticトークン参照を保持参照元が探索されなくても保持
@theme static inlineトークン値を一度置換参照元が探索されなくても保持

Inline 置換は間接参照を 1 段だけ取り除きます。置換した値の内部の参照は引き続きブラウザーが解決し、inline が再帰的に定数へ置き換えることはありません。@apply の展開も含む Master 生成の宣言に適用されますが、手書きのネイティブ CSS は元の var() 参照を保ちます。

残った変数が解決される場所

以下の 2 つの設定は、どちらも --color-brand: var(--app-brand) を定義して bg-brand を使い、inline 修飾子だけが異なります。どちらも文書のルートは青で、入れ子の section が --app-brand をプラム色に上書きします。

Inline 置換は残る参照を変える

どちらの例も同じマークアップで bg-brand を使います。通常のトークンはルートで解決した値を継承し、inline は生成宣言に、スタイルを適用する要素で --app-brand を参照させます。

テキストによる説明
  1. 両方の設定は --color-brand: var(--app-brand) を定義します。ルートは --app-brand を #1d4ed8 とし、入れ子の section が #86198f に上書きします。
  2. 通常の @theme では、bg-brand は background-color: var(--color-brand) を出力します。ルートは --color-brand を青と計算し、入れ子の参照元はその計算値を継承します。
  3. @theme inline では、bg-brand は background-color: var(--app-brand) を出力します。参照する要素は、section から継承したプラム色の値を読み取ります。
  4. スウォッチは結果の背景を示します。図のルートの値は計算値であり、コンパイラーが色を評価するという意味ではありません。

通常の @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 のスコープまたは条件であり、もう 1 つのトークン名前空間ではありません。トークン値の変更と、ルールをモードに限定することは別の操作です。

仕組み変わるもの有効にするもの
ネイティブカスタムプロパティの上書きそのスコープで継承する値記述したセレクターまたはネイティブクエリー
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)  }}

トークンの上書きは背景の値を変え、ミックスインは padding が作用する場所を変えます。どちらの仕組みも、もう一方を定義しません。ラッパーの引数と配置はユーティリティとミックスインを参照してください。

システム設定と手動のカラースキーム

完全なプリセットはネイティブの color-scheme ルールを提供します。ルートは light dark を許可し、data-theme="light" または data-theme="dark" は領域のスキームを固定します。トークンは light-dark(white, #111827) でそのスキームに従えます。値はブラウザーが選ぶため、2 つ目のクラスは不要です。ネイティブの動作は light-dark()を参照してください。

手動テーマの領域内でも、プリセットの @dark と @light はシステムのメディアクエリーのままです。data-theme を変えても有効になりません。色で手動の有効化と入れ子の領域を示しています。

ローカルな重複と Shadow DOM

重複するスコープは、レイヤー順序と詳細度も含む通常のカスケードに従います。セレクターがテーマを表しているだけで、ローカルな値が自動的に強くなるわけではありません。カスケードレイヤーを参照してください。

既定のテーマ宣言は :host を含みます。スコープ付きの host の上書きは明示し、必要なスタイルシートをシャドウツリーに読み込みます。

@theme {  --color-panel: white;}:host([data-theme="dark"]) {  --color-panel: #111827;}

トークンがリソース配信を代替することはありません。ネイティブキーフレームと依存関係の保持はキーフレームの仕様を、スタイルシートの保持はネイティブ CSS のプルーニングを参照してください。