TypeScriptの型定義のように、CSSのカスタムプロパティに対してルールを設定する方法について学びました。
@propertyとは
ルールを設定してカスタムプロパティを登録できる構文です。
設定できるルールです↓
- syntax(値のデータ型)
- inherits(プロパティ継承の有無)
- initial-value(初期値)
syntaxとinheritsはどちらも必須です。initial-valueは、場合によって省略可能です。
コード例です↓
@property --main-color {
syntax:"<color>";
inherits:true;
initial-value:#fafafa;
}
body {
background-color:var(--main-color);
}
以降より指定できるルールについて詳しく解説していきます。
syntax(値のデータ型)
このルールは、カスタムプロパティに値として指定できるデータ型を引用符で囲って定義します。
必須ルールです。省略すると無効になります。
以下2種類のルール指定方法が存在します↓
- 定義済みの型を使って指定
- 記号を使って指定
定義済みの型を使って指定
仕様で定義されている型を使うことができます。
以下のようなデータ型が指定できます↓
- <length>
- <number>
- <color>
コード例です↓
@property --property-name {
syntax:"<number>"; //単一のnumber型の値のみ受け入れる
//省略
}
その他に指定できる型は仕様書を確認してください↓
記号を使って指定
以下4種類の記号を使って定義できます↓
- プラス記号(+)
- ハッシュ記号(#)
- パイプ記号(|)
- アスタリスク記号(*)
スペース記号の値を受け入れる|プラス記号(+)
コード例です↓
@property --set-position {
syntax: "<length>+"; // スペース区切りのlength型の値を受け入れる
inherits: false;
initial-value: 50px 50px;
}
.hoge {
translate:var(--set-position);// xに50px、yに50px移動
}
カンマ区切りの値を受け入れる|ハッシュ記号(#)
コード例です↓
@property --main-color {
syntax: "<number>#"; // カンマ区切りのnumber型の値を受け入れる
inherits: false;
initial-value: 50,255,30;
}
body {
background-color: rgb(var(--main-color)); // rgb(50,255,30)
}
複数のルールを受け入れる|パイプ記号(|)
コード例です↓
//複数の決められたルールを繋ぐ
@property --property-name {
syntax:"<length> | <percentage>"; //長さまたはパーセント値を受け入れるが、両者を組み合わせた calc式は受け入れない(calc(50px * 10%)はだめ)))
//省略
}
//任意の値を繋ぐ
@property --property-name {
syntax:"small | medium | large"; //「small、medium、large」のいずれかを受け入れる
//省略
}
//任意の値と決められたルールとカスタムルールを繋ぐ
@property --property-name {
syntax:"small | <integer> | <color>#"; //「small、単一の整数、カンマ区切りの色リスト」のいずれかを受け入れる
//省略
}
全ての値を受け入れる|アスタリスク記号(*)
これが指定された場合のみ、initial-valueは省略可能です。
コード例です↓
@property --custom-property {
syntax: "*"; // 全ての値を受け入れる
inherits: false;
initial-value: 省略可能;
}
inherits(プロパティ継承の有無)
このルールにはtrueまたはfalseが指定できます。この指定は必須で省略すると無効になります。
true(継承あり)
親要素がカスタムプロパティの初期値を上書きした場合かつ、子要素がカスタムプロパティを指定しなかった場合、子要素のカスタムプロパティの値は親要素が上書きした値になります。
コード例です↓
@property --main-color {
syntax: "<color>";
inherits: true; //プロパティが継承される
initial-value: #000;
}
//親要素が初期値を上書き
.parentElement {
--main-color:#fafafa;// #fafafaに上書き
background-color:var(--main-color); // #fafafa
}
//子要素
.childElement {
background-color:var(--main-color); // #fafafa
}
false(継承なし)
親要素は関係なく、子要素がカスタムプロパティを指定しなかった場合、子要素のカスタムプロパティの値は初期値になります。
コード例です↓
@property --main-color {
syntax: "<color>";
inherits: false; //プロパティが継承されない
initial-value: #000;
}
//親要素が初期値を上書き
.parentElement {
--main-color:#fafafa;// #fafafaに上書き
background-color:var(--main-color); // #fafafa
}
//子要素
.childElement {
background-color:var(--main-color); // #000 初期値が設定される
}
initial-value(初期値)
このルールはカスタムプロパティの初期値を指定します。また、syntaxルールにアスタリスク記号(*)が指定されている場合を除き必須です。省略すると無効になります。
無効になる単位や値
指定する値は計算上独立している必要があり、以下の単位や値を指定すると無効になります。
- フォントに基づく相対単位(lh,emなど)
- ルート要素のフォントに基づく相対単位(rem,rcapなど)
- コンテナクエリの長さの単位(cqw,cqhなど)
- var()関数を使用したカスタムプロパティの値
これら以外の絶対単位(px,cmなど)やビューポートに基づく相対単位(vh,vwなど)を指定できます。
詳しくは仕様を確認してください↓
無効な書き方をした場合
@property構文でルールを指定して登録したが、そのルールに違反した書き方の場合、プロパティの値は登録された初期値を設定します↓
Registering a custom property must not affect the cascade in any way. Regardless of what syntax is specified for a registered property, at parse time it is still parsed as normal for a custom property, accepting nearly anything. If the specified value for a registered custom property violates the registered syntax, however, the property becomes invalid at computed-value time (and thus resets to the registered initial value).
4.1. The registerProperty() Function
コード例です↓
@property --main-color {
syntax: "<color>";
inherits: false;
initial-value: #000;
}
body {
--main-color:10;//ルール違反
background-color: var(--main-color); // 10は無視されて#000が入る
}
構文を使わずに書いた場合との違い(アニメーション可能になる)
@property構文を使わずにそのままカスタムプロパティを登録した場合、アニメーションタイプが離散型のためアニメーション不可ですが、構文を使用するとカスタムプロパティのアニメーションが可能(補間が効く)になります。
グラデーションに対して補間したり、シンプルなテキストのカウントアップアニメーションが可能になります。
@propertyを使用したアニメーションの例
全ての例がFirefoxで動きません。
テキストのグラデーションが変化する↓
See the Pen gradation text by ユイト (@mikiprogram) on CodePen.
mask-imageと組み合わせ↓
See the Pen mask-image and @property by ユイト (@mikiprogram) on CodePen.
数字のカウントアップ(Safariは動かない)↓
See the Pen count up number by ユイト (@mikiprogram) on CodePen.
ブラウザ対応状況
現時点(2023年9月22日)ではFirefox以外対応しています。Firefoxは124から対応します。
ブラウザ対応状況について確認する↓