カスタム プロパティ

サイトの初期スタイルをいくつか作成しているときに、CSS の値の一部が重複していることに気づいたとします。dodgerblue をメインカラーとして使用し、ボタンの枠線、リンクテキスト、ヘッダーの背景に追加しています。また、デザインツールを使用して、サイトの他の部分にその青色のバリエーションをいくつか選択しています。スタイルガイドが取得され、プライマリ カラーが oklch(70% 0.15 270) になります。

カスタム プロパティ(CSS 変数)を使用すると、CSS の値を整理して再利用できるため、スタイルをより柔軟に、よりわかりやすくすることができます。

プロパティの作成

プロパティを作成する最も簡単な方法は、定義した名前の新しいプロパティに値を設定することです。

.card {
  --base-size: 1em;
}

すべてのプロパティ名は 2 つのダッシュで始める必要があります。これにより、既存の CSS プロパティ名をカスタム値に使用しようとすることが防止されます。CSS 仕様では、2 つのダッシュで始まるプロパティが追加されることはありません。

このプロパティには、var() 関数でアクセスできます。この例では、.card-title 内のフォントサイズを --base-size 値の 2 倍に設定しています。

.card .card-title {
  font-size: calc(2 * var(--base-size));
}

カスタム プロパティを使用する

前に見たとおり、カスタム プロパティの値は var() 関数で使用できます。var() 関数は値では使用できますが、メディアクエリでは使用できません。特に、他の CSS 関数の引数として使用すると便利です。

フォールバック

値が設定されていないカスタム プロパティを使用しようとするとどうなりますか?var() 関数は、フォールバック値として使用される 2 番目の値を受け取ります。フォールバック値は、ネストされた var() を含む別のカスタム プロパティにすることもできます。

#my-element {
  background: var(
    --alert-variant-background,
    var(--alert-primary-background)
  );
}

無効な値

カスタム プロパティが background-color プロパティの 1em などの無効な値に解決される場合、そのプロパティのその要素の他の有効な宣言は使用されません。これは、ブラウザが値を計算するときに他の宣言を破棄するまで、値が無効かどうかを判断できないためです。代わりに、使用される値は継承された値または初期値になります。

.content {
  background-color: blue;
}

.content.invalid {
  --length: 2rem;
  background-color: var(--length);
}

上記の例では、.invalid 要素の背景は青になりません。代わりに、background-color は継承されないため、値は初期値の transparent になります。

オーバーライドと継承

ほとんどの場合、カスタム プロパティのデフォルトの動作(値の継承)が望ましいでしょう。プロパティに新しい値を設定すると、その要素とそのすべての子要素にその値が適用されます。別の値でオーバーライドされるまで、その値が使用されます。

カスタム プロパティはカスケードによって決定されるため、より具体的なセレクタでオーバーライドすることもできます。

@property による制御の強化

値を設定して作成されたカスタム プロパティは、任意の型にすることができ、継承されます。カスタム プロパティをより詳細に制御するには、@property ルールを使用します。

以前に作成した --base-size プロパティは、この @property 宣言と同等になります。

@property --base-size {
  syntax: "*";
  inherits: true;
  initial-value: 18px;
}

syntax 値は、プロパティに有効な CSS 値の型を設定します。そのプロパティに別の型を設定すると、無効になり、初期値またはカスケードの上位で設定された継承値にフォールバックします。

@property を使用してカスタム プロパティを作成するときに、inherit: false を使用して継承を無効にできます。継承が無効になっているカスタム プロパティの値をオーバーライドすると、選択した要素の値は変更されますが、その子要素の値は変更されません。これは、複数のセレクタが同じ要素をターゲットとする場合に便利です。

initial-value は、後で変更されない限り、プロパティの値を設定します。構文が *(任意の CSS 型)でない限り、@propertyinitial-value を設定する必要があります。これにより、プロパティには常に指定された構文の値が設定され、未定義になることはありません。

JavaScript を使用してカスタム プロパティを更新する

要素のカスタム プロパティの値は JavaScript を使用して更新できます。これを使用して、サイトのスタイルを動的に更新できます。

const element = document.getElementById("my-button");
getComputedStyle(element).setPropertyValue("--color", orange);

この例では、#my-button 要素の style タグを更新します。DevTools で検査すると、次のようになります。

<button id="my-button" style="--color: orange">Click me</button>

上記の例では、カスタム HTML 属性に保存されているデータにアクセスして、カスタム プロパティを設定する方法を確認できます。各ボタンには、特定の色を表す値を持つ data-color 属性があります。body 要素に設定された --background カスタム プロパティは、クリックされたボタンの data-color の値にリセットされます。

getComputedStyle(element).getPropertyValue("--variable") を使用して、特定の要素のプロパティの値を取得することもできます。これは、ロジックがカスケード値に応答する必要がある場合に便利です。