大規模なスタイルシートを管理すると、特にグラデーションやレスポンシブ レイアウト パターンなどのデザイン システム トークンを扱う場合に、ロジックが重複することがよくあります。
CSS の @function アットルールを使用すると、このロジックを再利用可能なパラメータ化された関数にカプセル化できるため、CSS の保守性、一貫性、DRY(Don't Repeat Yourself)が向上します。
@function 構文
カスタム関数は、@function ルール、ダッシュ付きの名前、パラメータのリストを使用して定義されます。この関数は、result プロパティを使用して値を返します。
@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
/* Logic goes here */
result: var(--input1);
}
主な概念
- パラメータ: 先頭は 2 個のダッシュ(
--)にする必要があります。 - デフォルト: コロン(
:)を使用してデフォルト値を指定できます。 - 結果:
resultプロパティによって、関数が返す値が決まります。関数本体で最後に宣言されたresultが優先されます。 - スコープ設定: 関数内で定義されたパラメータと変数は、ローカル スコープになります。
- 型: パラメータと戻り値が CSS 型と一致するように、ブラケット表記(例:
<color>)で指定できます。また、type関数(例:type(<number> | <percentage>))を使用して複数の型を許可することもできます。
実際の例
1. デザイン システム トークン(グラデーション)
グラデーション ロジックをカプセル化することで、アプリ全体で一貫したカラー グラデーションを実現します。--angle は、オーバーライド可能な一貫性を提供するデフォルト値を提供します。
@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}
.card {
background: --fancy-gradient(#ed73d7, #5d87e9);
}
2. 条件付きレイアウト ロジック
@media などのクエリを関数内で直接使用して、環境に応じて異なる値を返すことができます。関数内で条件付きロジックを使用する場合、@function は result の最初の値で「戻る」のではなく、CSS カスケードに従い、画面サイズ、コンテナサイズ、またはその他のクエリに基づいて一致する最後の値に解決されることに注意してください。
@function --grid-template(--count <number>){
/* MANDATORY: Put default value first. */
result: 1fr; /* Default: stack */
@media (min-width: 800px) {
result: repeat(var(--count), 1fr); /* Grid on larger screens */
}
}
main {
display: grid;
grid-template-columns: --grid-template(2);
}
ベスト プラクティス
- ダッシュ付きの名前を使用する: 関数名とパラメータの先頭には必ず
--を付けます。 - デフォルト値を指定する: 適切なデフォルト値を指定することで、関数の堅牢性を高めます。
- シンプルさを心がける: 実際には繰り返しや複雑なロジックに関数を使用します。単純なプロパティと値のペアを過剰に設計しないでください。
- 型を使用する: パラメータと戻り値が想定される型であることを確認します。
- プリコンパイルされた代替手段を検討する: ユーザー入力、メディアクエリ、その他のクライアントサイドのバリエーションに依存しない関数の場合は、CSS プリコンパイラを使用して、クライアントで不要な処理を行わないようにすることを検討してください。
代替戦略
CSS 関数をサポートしていないブラウザでは、CSS 関数を使用して設定された値は無効になります。他のブラウザをサポートするには、まずプロパティのフォールバック値を指定します。これは、CSS 関数をサポートするブラウザでオーバーライドされます。
.card {
/* Provide fallback, in this case a solid color. */
background: #5d87e9;
background: --fancy-gradient(#ed73d7, #5d87e9);
}
main {
/* Provide fallback, in this case a simple stacked default. */
grid-template-columns: 1fr;
grid-template-columns: --grid-template(2);
}
他のブラウザをサポートしながらスタイルの繰り返しを減らす必要がある場合は、Sass などの関数を備えた CSS プリコンパイラを検討してください。