これは朗報! CSSだけで関数とミックスインが使えるように
Post on:2024年3月5日
CSSは変数(カスタムプロパティ)をはじめ、最近では入れ子(ネスト)もサポートされ、進化を続けています。これはまだ先のことだと思いますが、Sassなどのプリプロセッサで使用できる関数とミックスインをCSSで使えるようにしようという動きがあります。
もちろん仕様などはまだ決まっていませんが、CSSで@function
と@mixin
の2つのatルールが提案されています。
Future of CSS: Functions and Mixins
by Andrew Bone
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
この記事ではこれからのCSSとして、まだブラウザでは使用できませんが、CSSの記述方法を変える可能性のあるものを見ていきます。それはcsswg-draftsで提案されているCSSによる関数とミックスインです。
CSSによる関数とミックスインは一言で説明すると、プリプロセッサを使用せずにCSSのロジックを再利用できるようになります。これにより、ユーティリティクラスを使うことなく、CSSでDRY原則を実施できます。
この機能のここまでの経緯とこれらの変更が実際にどのような意味を持つのか解説しようと思います。
CSSのプリプロセッサ
従来のCSSには、変数、入れ子、ミックスイン、関数といった機能が欠けていました。そのため、CSSはすぐに複雑で面倒なものになってしまうことが多く、デベロッパーをイライラさせていました。そこで登場したのが、CSSプリプロセッサです。プリプロセッサはコードを簡単にし、反復を少なくさせました。
プリプロセッサが理解する形式でCSSを記述すれば、ビルド時に素晴らしいCSSを得られます。一般的なプリプロセッサには、Sass, Less, Stylusがあります。その中からこの記事では、Sassを取りあげます。
プリプロセッサに問題がなかったわけではありません。
1つ目は、ブラウザがプリプロセッサが何をしているか理解できないため、ビルド・コンパイルのステップが必要になることです。2つ目は、プリプロセッサに互換性がないことです。それぞれのプリプロセッサで構文が微妙に異なるため、デベロッパーはそれぞれを学んでマスターする必要があります。
これを改善する試みとして、あるいは単にバニラDX(Developer eXperience)を向上させる方法として、CSSの仕様は変数をはじめ、最近ではCSSネストで入れ子が使えるようになりました。
Sassの@function
@function
を使用すると、スタイルシート全体で再利用できるSassScript値に対する複雑な動作を定義できます。一般的な計算式やビヘイビアを読みやすい方法で簡単に抽象化できます。
Sassの@functionは、デベロッパーは単一の値を計算することができます。これはビルド時に計算されるため、標準のCSS変数を含めることはできません。
Sassの@mixin
@mixin
を使用すると、スタイルシート全体で再利用できるスタイルを定義できます。たとえば、.float-left
のような非セマンティックなクラスの使用を回避したり、ライブラリにスタイルのコレクションを分散させることが簡単になります。
Sassの@mixinは、デベロッパーはCSSのブロック全体(プロパティと値のペア)を@include
することができます。また、ブロックを変更できる引数を渡すこともできます。ただし、これもビルド時に計算されるため、標準のCSS変数を含めることはできません。
実際の使用例
たとえば、デザインシステムに異なる色のボタンがあるとします。
異なる色のボタン
各ボタンは色が異なることを除けば同じです。また、ホバー時とアクティブ時は、ベースカラーより少し暗い色になります。
まず、任意の色を設定した割合でブラックと混ぜる関数を用意します。
1 2 3 |
@function --darken(--base, --percent) { @return color-mix(in srgb, var(--base), #000 var(--percent)); } |
CSSの関数は値(文字列、色、長さなど)を返し、CSSの宣言内で使用できます。
これでベースカラーを暗くする関数ができたので、ホバー時とアクティブ時のボタンスタイルを作成するmixinを作成します。@mixin
でネストを使用すると、簡単にできます。
引数の--color
にはデフォルトカラーが設定されており、指定されていない場合に適用されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@mixin --button(--color: #174D7C) { background-color: var(--color); color: white; border: none; padding: 0.5rem 1rem; border-radius: 4px; font-size: 1rem; cursor: pointer; &:hover { background-color: --darken(var(--color), 5%); } &:active { background-color: --darken(var(--color), 10%); } } |
CSSのミックスインはCSSの宣言全体、またはルールブロック(セレクタやその他の@
ルールを含む)を返します。
あとは、デフォルトカラーを使用したボタンを設定し、グリーンとオレンジのボタンも設定します。
1 2 3 4 5 6 7 8 9 10 11 |
.primary-btn { @apply --button } .green-btn { @apply --button(#6F9F9C) } .orange-btn { @apply --button(#FE5F55) } |
これで完成です。
異なる色のボタン
このようにして、CSSの大部分が一度だけ記述され、ほかのすべては実行時に計算される3つのボタンが実装できました。つまり、ネイティブのCSS変数をフルに活用できます。
終わりに
CSSの変化の蛇口が閉められてきたなと思った矢先に、このような巨大なものがやってきました。この仕様が確定し、ブラウザに実装されるまでには時間がかかると思いますが、その可能性にはただただ驚かされます。
ここまで読んでくれて、ありがとうございます。私と繋がりたいひとは、@Link2TwentyやLinkdinにアクセスしてください
sponsors