はじめに
みなさんは、CSSで関数を定義したいと思ったことはありますか?
- 余白のスケールを自動でそろえる関数を作りたい
- レイヤーに応じたドロップシャドウの値を返す関数を作りたい
など
実は、Chrome 139以降では、プレーンなCSSに関数を定義できるようになりました。
そのため、この記事では、Custom Functionsについて紹介します。
Custom Functionsとは?
Custom Functionsは、独自の関数を定義することができるアットルール(@function)です。
れにより、Sassのように関数を使って計算や再利用ができるようになります。
See the Pen @function by degudegu2510 | Qiita (@degudegu2510) on CodePen.
基本構文
Custom Functionsの基本的な構文は、以下のようになります。
@function --spacer( --value ) {
result: calc(8px * var(--value));
}
.sample {
padding: --spacer(2); /* 16pxになる */
}
複数の引数を定義したい場合は、こんな感じになります。
@function --spacer( --value-a, --value-b ) {
result: calc(var(--value-a) * var(--value-b));
}
引数の型を定義する
以下のように、--value:の後にcssのデータ型を記述することで、引数の型を定義することができます。(省略可)
@function --spacer( --value: <length> ) {
result: calc(8px * var(--value));
}
戻り値の型を定義する
以下のように、returns <データ型>になるように記述することで、戻り値の型を定義することができます。(省略可)
@function --spacer( --value ) returns <length> {
result: calc(8px * var(--value));
}
Custom Functionsの使い方
Custom Propertyを使う場合
Custom Functions内でもCustom Property(CSS変数)を利用できますが、スコープと優先度に注意が必要です。
関数内で再定義した変数は、グローバルよりも優先されます。
:root {
--default-space: 4px;
}
@function --spacer( --value ) {
--default-space: 8px;
result: calc(var(--default-space) * var(--value));
/* 8px x var(--value) で計算される */
}
アットルールを使う場合
@media などのアットルールも関数内で使用できますが、書く位置に制限があります。
アットルールを使いたい時は、resultの後に定義しましょう。
@function --spacer( --value ) {
result: calc(8px * var(--value));
@media (width < 400px) {
/* 画面幅が400px以下の時に↓このスタイルが当たる */
result: calc(4px * var(--value));
}
}
以下の例のように、resultの前でアットルールを使うことはできません。
/* ❌ このようなことはできません ❌ */
@function --spacer( --value ) {
@media (width < 400px) {
result: calc(4px * var(--value));
}
result: calc(8px * var(--value));
}
もしresultの前で条件を分けたい場合は、Custom Propertyを使って変数に値を設定する方法が有効です。
:root {
--default-space: 8px;
}
@function --spacer( --value ) {
@media (width < 400px) {
--default-space: 4px;
}
result: calc(var(--default-space) * var(--value));
}
まとめ
Custom Functionsを使うと、CSSだけで計算ロジックや再利用可能なスタイルルールを表現できるようになります。
Sassのようなプリプロセッサを使わずに、スタイル設計ができる時代に変わってきたことを実感します。
最後まで読んでくださってありがとうございます!
普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。