ナビゲーション

Directives

ユーティリティとミックスイン

必要に応じて生成するユーティリティ、再利用可能なミックスイン、レイヤーに属するネイティブスタイルを定義します。

このページの内容

@utility は必要時に生成するクラスを登録します。@mixin は再利用する CSS 本体に名前を付け、@apply は呼び出し位置で展開します。ネイティブセレクターは通常の CSS のままです。形式の選び方はスタイルの再利用で説明し、このページでは文法と置換規則を定義します。

@utility

最上位でクラスの形式を明示的に宣言します。

@utility card-layout {  display: grid;  gap: var(--spacing-md);  &:hover {    outline: 1px solid currentColor;  }}@utility col-gap-(--spacing) {  column-gap: var(--spacing);}@utility grid-cols(--cols <integer>) {  display: grid;  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));}

マークアップでは card-layout、col-gap-sm、grid-cols(3)@sm を使います。ヘッダーで固定クラス、トークンパターン、関数のどれを登録するかが決まります。各形式はその形式だけを登録し、トークンパターンは関数呼び出しも作るわけではありません。宣言や対応する入れ子規則を加えても登録は変わりません。

ユーティリティ名とトークンの接頭辞には _ を含められません。クラス内では _ が子孫セレクターを始めるため、その定義のソース位置でエラーを報告します。トークンキーには _ を含められ、var() で使える変数として有効ですが、単独のトークンクラスや補完は作りません。ミックスイン 名、カスタムプロパティ、ネイティブスタイルシートのクラスは引き続き _ を使えます。

登録とプリセット

テーマはトークンを供給し、ユーティリティ定義はそこから生成できるクラスを決めます。完全なプリセットには "@master/css" をインポートします。スタイルシートを明示的に組み立てる場合は、独自トークンとともに "@master/css/utilities.css" を読み込めます。

トークンとプロパティの完全な対応はファミリー一覧、それぞれの登録は固定ユーティリティと直接数値を参照してください。すべてここで説明する同じ定義形式を使います。

トークンパターン

パターンは末尾にプレースホルダーを 1 つ持ちます。パラメーターがトークンの名前空間、固定部分がクラスの接頭辞を指定します。型なしのプレースホルダーはトークン値を束縛します。

@utility p-(--spacing) {  padding: var(--spacing);}@utility m-(--spacing) {  margin: var(--spacing);}@utility fg-(--color) {  color: var(--color);}@utility size-(--spacing) {  width: var(--spacing);  height: var(--spacing);}

p-md は var(--spacing-md) を束縛し、size-md は両宣言でその参照を使います。通常のトークンはブラウザー評価の参照を保持し、inline トークンは宣言値を一度代入します。未知のトークンはクラスを作りません。値パターンは数値や Unicode のキーを受け付け、-- を含むキーも可能です。

<string> のプレースホルダーはトークンキーを束縛し、補助値の明示的な参照を可能にします。

@theme {  --text-hero: var(--font-size-5xl);  --text-hero--line-height: 1.15;  --text-hero--letter-spacing: -.03em;}@utility text-(--text <string>) {  font-size: var(ident("--text-" var(--text)));  line-height: var(ident("--text-" var(--text) "--line-height"), normal);  letter-spacing: var(ident("--text-" var(--text) "--letter-spacing"), normal);}

text-hero は文字列 "hero" を束縛し、対応する主トークンが必要です。-- を含む補助キーはクラスを作らず、補助値がなければ記述した代替値を使います。ident() は静的に通常の CSS 識別子へ畳み込みます。名前空間はパラメーターから取るため、@utility type-(--text <string>) は同じトークンを別のクラス接頭辞で使います。トークンのプレースホルダーは既定値や他の型を受け付けません。

共通の接頭辞で複数の名前空間を明示的に公開できます。

@utility font-(--font-family) {  font-family: var(--font-family);}@utility font-(--font-size) {  font-size: var(--font-size);}@utility font-(--font-weight) {  font-weight: var(--font-weight);}

font-sans、font-sm、font-bold は、そのキーを持つ唯一の名前空間をそれぞれ選びます。複数分岐に同じキーがあれば、使用時に AMBIGUOUS_TOKEN を報告し CSS は生成しません。キーを分けるか、(font-size:var(--font-size-brand)) などのネイティブ宣言を使います。この規則は文字列キーのレシピや複数宣言の本体にも適用します。負の値と不透明度は一意な分岐の選択後に検査します。

固定クラスはパターンに優先します。予約されるのはトークンキーではなくクラスの完全な綴りです。そのため --text-center があっても text-center は text-align を設定しますが、fg-solid、b-solid/.5、-mx-auto は solid や auto というトークンを使えます。パターンは最長の接頭辞を選び、選んだファミリーにトークンがなければ短い接頭辞を再試行せずエラーを報告します。パラメーターの名前空間が異なるパターンは同じ接頭辞で共存できます。後のパターンは、デコード後の接頭辞と名前空間が同じ定義を、パラメーターモード、本体、ソース、依存先ごと完全に置換します。静的登録と関数登録は、同形式・同名の定義を独立して置き換えます。

負の値と不透明度は直接値の部分集合に適用します。型なしのプレースホルダー 1 個と、値全体が var(--parameter) であるネイティブ宣言 1 個が条件です。-m-md は数値の余白トークンを負にし、-p-md は padding が負に対応しないため無効です。fg-red/.5 は色トークンに 0 から 1 の不透明度を適用します。通常の複数宣言や文字列キーのレシピには広がりません。

2 つの名前空間の一致は 2 宣言を生成しない

この独自テーマには両トークンキーが存在します。Master CSS はクラス生成前に名前空間を一意に選ぶ必要があります。

テキストによる説明
  1. --font-family-brand: monospace と --font-size-brand: 2rem があると、font-brand は 2 つのプリセットの font- ファミリーに一致します。
  2. 結果は AMBIGUOUS_TOKEN で、そのクラスの CSS は生成しません。分岐は結合しません。
  3. キーを分けるか、(font-size:var(--font-size-brand)) のような明示的なネイティブ宣言を使います。

静的な引数

関数ユーティリティと ミックスイン は、型なし、<integer>、<number>、<string>、<custom-ident> の位置パラメーターを受け付けます。静的な既定値は --cols <integer>: 2 のようにコロンで指定します。数値は数値リテラルで、グリッド数とスパンは正の整数が必要です。文字列引数には引用符が必要です。

@utility pair(--size) {  width: var(--size);  height: var(--size);}

pair(2rem) のように使います。一般の関数引数は静的に確定する必要があります。関数または ミックスイン が、型なし・既定値なしのパラメーターを 1 つだけ持ち、値全体が var(--parameter) のネイティブ宣言 1 個だけで構成される場合は、記号的な var() 式も受け付けます。呼び出し元の参照はブラウザー評価用にそのまま保ちます。他の関数は外部の var()、attr()、ブラウザー依存の引数を拒否します。既知の外側のパラメーターは var(--parameter) で転送できます。

A parameter utility

@utility pair(--size) { width: var(--size); height: var(--size); } @safelist 'pair(2rem)';
生成された CSS
@layer utilities {  .pair\(2rem\) {    width: 2rem;    height: 2rem  }}

静的なレシピ引数と動的な CSS 値は異なる

図の pair ユーティリティは宣言が 2 つあります。別に設けた単一パラメーター・単一宣言の記号参照の例外は適用しません。

テキストによる説明
  1. @utility pair(--size) { width: var(--size); height: var(--size); } は pair(2rem) の既知の引数を受け取り、両宣言に束縛します。
  2. このレシピはブラウザー依存の引数である pair(var(--size)) を拒否します。動的に保つ値には明示的なネイティブ宣言クラスを使います。
  3. (width:var(--size)) は変数参照をブラウザー用に保ち、幅だけを変えます。高さも必要なら別の高さ宣言を加えます。

@mixin と @apply

Master は実験的な CSS Mixins 仕様の静的な部分集合をコンパイルします。定義は二重ハイフンで始まる名前を持ち、無条件のスタイルシートレベルの規則でなければなりません。ミックスイン は CSS の再利用用で、Master クラスは登録しません。

@mixin --caption {  font-size: var(--font-size-sm);  line-height: 1.5;}.caption {  color: currentColor;  @apply --caption;  font-weight: 600;}@utility caption {  @apply --caption;}

@apply はネイティブ規則、ユーティリティ、別の ミックスイン 内で ミックスイン 呼び出しを 1 つ受け付けます。ユーティリティ名やクラスリストは受け付けません。元の宣言位置で展開し、重複、重要度、セレクター、条件、URL の所有権を保持します。

パラメーターは &:hover や条件ラッパーを含め、適用先の要素で使えます。別要素での使用、再代入、セレクターや条件への補間、再帰定義、オーバーロード、@private、未対応の型はコンパイルエラーです。この静的部分集合はブラウザー依存のパラメーター評価、私有プロパティ、汎用関数を実装しません。

ミックスインは呼び出し位置で展開

挿入箇所の前後で対応する行を揃えています。セレクター、宣言順、外側のレイヤーは呼び出し元のままです。

テキストによる説明
  1. --caption ミックスインは font-size: 14px と line-height: 1.5 を供給します。
  2. .caption 内の @apply --caption は color: currentColor と font-weight: 600 の間で展開します。
  3. 展開はクラスを登録せず、ネイティブ規則を生成レイヤーに移しません。重複宣言と記述順を保持します。

内容とクラスラッパー

@contents は、呼び出し元の宣言や入れ子規則を再利用ラッパーのどこに入れるかを示します。

@mixin --card-wide() {  @container card (width >= 40rem) {    @contents {      display: grid;    }  }}.card {  @apply --card-wide {    gap: 1rem;  }}

@contents; は渡された内容を挿入します。@contents { … } は呼び出しでブロックを省略した場合だけ代替内容を供給します。明示的に空の @apply --card-wide {} を渡すと代替内容を抑制します。各 contents 位置にブロックを 1 回挿入し、宣言、重複、入れ子規則を保持します。@contents のない ミックスイン は渡されたブロックを無視します。

contents ブロックの省略と空は異なる

ミックスインは @contents { display: grid; } を持ちます。呼び出し側の波括弧で、意図的な空ブロックと省略を区別します。

テキストによる説明
  1. @apply --panel; は contents ブロックを省略し、代替の display: grid を使います。
  2. @apply --panel {} は空ブロックを渡して代替を抑制するため、この例では宣言を加えません。
  3. @apply --panel { display: flex; } は独自の内容で代替を置き換え、2 つの display 宣言は結合しません。

渡された内容は、入れ子の適用で転送しても呼び出し元のパラメーター束縛を保ちます。代替内容は定義元 ミックスイン の束縛を使います。通常のカスタムプロパティはネイティブ CSS のカスケード動作を保ちます。有限の入れ子呼び出しは可能ですが、再帰定義や展開の深さ・ノード数の上限超過はエラーです。

@mixin --hocus {  &:is(:hover, :focus-visible) {    @contents;  }}@utility emphasis {  color: red;  display: block;}
<button class="(color:red)@apply(--hocus)">Save</button><div class="grid-cols(3)@apply(--card-wide)"></div><div class="emphasis@apply(--hocus)!"></div>

@apply(--name(...)) は静的な引数を受け付けます。複数の @ ラッパーは左から右へ入れ子になり、(color:red)@apply(--a)@apply(--b) では --a が --b の外側です。ユーティリティは宣言を 1 ブロックとして渡すため、ラッパー自身の宣言はクラスごとに 1 回出力します。セレクター接尾辞は位置を保ち、末尾の ! は展開した全宣言を重要にします。クラスの先頭部分と @apply 以外の条件接尾辞が並び順を決めます。外側の条件分岐はそれぞれ独立して並ぶ規則となり、ミックスイン 内のセレクターや条件は出力テキストに残ってクラスを後の段階へ移さず、展開は記述順を保ちます。宣言、セレクター、条件を加えない展開は単一宣言ユーティリティと、先頭部分が (property:value) ならネイティブ宣言と並びます。それ以外はレシピとして並びます。検査と競合判定は展開後の規則を使います。

未使用の定義、破棄された contents、未使用の代替ブロックはトークンやキーフレームを保持しません。配信されるネイティブ @apply は emitted-globals 契約を通じてリソースの起点となります。宣言位置と相対 URL は定義元または呼び出し元のファイルを保持します。

ラッパーが呼び出し元の宣言を配置

強調したスロットと挿入宣言はセレクターの境界内の同じ位置です。ラッパーが宣言の適用先を制御します。

テキストによる説明
  1. @mixin --hocus { &:is(:hover, :focus-visible) { @contents; } } は明示的な contents スロットを持つセレクターラッパーを定義します。
  2. underline@apply(--hocus) は text-decoration-line: underline をスロットに渡します。出力規則はどちらの状態でも起点の要素に一致します。
  3. 位置を読みやすくするため、図の結果はエスケープされた起点クラスを & と略記します。生成 CSS は完全な起点を保持します。

定義全体の置換

後の定義は同じ登録の本体全体を置き換え、宣言を結合しません。同名の静的ユーティリティと関数ユーティリティは別登録です。トークンパターンはデコード後の接頭辞と名前空間が同じ分岐だけを置き換えます。

@utility badge {  color: red;  padding: 1rem;}@utility badge {  color: blue;}

badge は color: blue だけを出力します。前の padding とその依存先はなくなります。

後の定義が登録全体を置換

両定義は同じ静的ユーティリティを登録します。2 番目の定義が最初の定義全体を置き換え、元の padding も残りません。生成前の定義置換であり、2 つの CSS 規則がカスケードで競う場面ではありません。

テキストによる説明
  1. 最初の静的 badge 定義は color: red と padding: 1rem を持ちます。
  2. 後の静的 badge 定義は color: blue だけを持ち、最初の定義全体を置換します。
  3. badge を使うと color: blue を持つ 1 規則を生成し、前の padding と依存先は残りません。
  4. 静的登録と関数登録は独立です。トークンパターンは同じ接頭辞と名前空間の分岐だけを、ミックスインは名前付き定義全体を置換します。

ミックスイン 名にはパラメーター一覧、本体、依存先を含む最終定義が 1 つだけあります。空の定義も登録は残ります。前方への入れ子呼び出しは最終的な登録情報で解決し、パラメーターのオーバーロードはありません。

静的な名前と関数は別々の登録

経路は登録の同一性を示します。同名でもオーバーロードや結合された本体にはなりません。

テキストによる説明
  1. @utility badge { display: inline-block; } は静的 badge クラスを、@utility badge(--inset) { padding: var(--inset); } は別の関数を登録します。
  2. 静的定義を display: block に置換すると badge は変わりますが、badge(8px) は引き続き padding: 8px を書き込みます。
  3. 置換は同形式・同名の本体全体に作用します。関数は静的クラスの代替ではありません。

定義のスコープとインポート

@theme、@utility、@mixin、@custom-media、@custom-container は最上位の定義です。レイヤーや条件ラッパー内での登録はエラーです。ミックスイン 本体には宣言、入れ子セレクター、対応するネイティブ条件、入れ子の @apply、@contents を含められます。レイヤーへの配置は呼び出し箇所で決めます。

ソーススキャン、セーフリスト、エンジン API、ランタイムの DOM 変更によるクラスが使用の起点です。配信するネイティブ CSS 内の @apply も起点ですが、未使用のユーティリティや ミックスイン、未配信の @reference スタイルシート内のものは違います。依存収集はパラメーター束縛と ident() の畳み込み後です。使用するトークンは宣言順と推移的な依存を保持します。静的トークンは参照元がなくても起点のままです。最後の起点を除くとリソースを解放し、ネイティブ CSS のリソースは emittedGlobals で固定します。

ランタイム manifest は将来の DOM クラス用に未使用定義を保持します。オンデマンド生成の対象は CSS とリソース出力です。ネイティブ CSS のプルーニングは明示的な有効化が必要で、キーフレームは宣言ファイルのネイティブ保持・プルーニング方針に従います。修飾付きインポートにはネイティブ CSS だけを含め、定義は修飾なしのインポートや参照で読み込みます。

ネイティブプロパティの優先順

ネイティブの (property:value) クラスは、ユーティリティ登録と独立して CSS プロパティの意味を保ちます。同条件では単一宣言ユーティリティやネイティブ宣言クラスでレシピの一部を上書きできます。完全な並び順と上書き規則は宣言と値を参照してください。

ネイティブの既定スタイル

ネイティブの既定スタイルは @layer defaults に書きます。

ネイティブコンポーネント

ネイティブのコンポーネントセレクターは @layer components に書きます。

@layer components {  .button {    display: inline-flex;    padding: var(--spacing-md);    &:focus-visible {      outline: 2px solid currentColor;    }  }}

ネイティブ規則はスタイルシートのインポートグラフに従って配信します。ユーティリティ定義はクラス名を登録し、ミックスイン 定義は @apply による CSS の再利用を提供します。どちらもコンパイル時に処理し、使用時だけ CSS を出力します。

Sass との相互運用

Sass を使う場合は CSS ミックスイン 定義を .css ファイルに置きます。現在の Dart Sass は将来の CSS 対応のため @mixin --name を予約し、Sass ミックスイン として拒否します。Sass の互換性に関する告知を参照してください。SCSS ファイルでは Master CSS のコンパイル前に、補間でネイティブ at-rule を出力できます。

@#{'mixin'} --card {  padding: 1rem;}.card { @apply --card; }

これは Sass の補間であり、追加の Master CSS 構文ではありません。Sass の @include と CSS の @apply は別の構造です。

テーマセレクターのラッパー

ネイティブのセレクターとクエリがテーマの上書きを有効にします。ミックスイン で対応するクラス条件を提供できます。

@mixin --ocean {  &:where([data-theme="ocean"], [data-theme="ocean"] *) {    @contents;  }}

(color:white)@apply(--ocean) を使います。シャドウホストを対象にする場合は :host(...) セレクターを明示的に加えてください。