
こんにちは。3年目のユーヤです。
今回のブログは、コーディングに便利なCSS変数についてのお話です。
長めの前置き
Adobe XDのサポートが終了してもう1年が経とうとしていますね。弊社でもデザインツールがfigmaに移行して、コーディング時にスタイルやらテキストやらを直接コピーできる便利さに甘え切ってしまっているのですが、あるとき問題が発生してしまったのです。
というのも、複数パターンがあるパーツの色指定にCSS変数を使っていたのですが、背景色に透明度が指定されているけど中に別の要素が入るからopacityは使えない、といったパーツでSassのrgba($color, $alpha)を使って半透明な色指定をしようとしたのです。ところが出力を見ると色が出ていませんでした。検証ツールで見ると、
background-color: rgba(#ddd, 0.7);
となっていました(数値は仮に色を#ddd、透明度を0.7としています。)。本来であれば、コンパイル時にHex値からrgb値に変換されて
background-color: rgba(221, 221, 221, 0.7);
とならなければなりません。どうやらCSS変数で指定したカラーコード#dddが文字列として処理されてしまっているようです。
これは、Sass関数とCSS変数の評価タイミングの違いによるものです。
Sass関数はCSSへのコンパイル前に実行されますが、CSS変数はコンパイル後、ブラウザ上で表示されるタイミングで値が評価されます。つまり…
(scss)background-color: rgba($color: var(--mainColor), $alpha: 0.7);
↓コンパイル
(CSS)background-color: rgba(var(--mainColor), 0.7);
↓CSS変数に値を代入
(ブラウザ上)background-color: rgba(#ddd, 0.7);
というわけです。ですので、どんなに頑張ってもSass関数にカラーコードのCSS変数は使えない、ということになります。
これを回避するには、Sass関数ではない方法で記述する必要があります。
たとえば、上にもあるCSSのrgba()関数や、色相(Hue)、彩度(Saturation)、明度(Lightness)を指定するhsla()関数が挙げられます。
しかし、これらはそれぞれ色を3つの値で決定するためCSS変数を3つに分ける、ないし3つまとめて指定する必要があります。ですがせっかくHex値でコピーしてきた色を毎回rgb値やhsla記法に改めるのは手間がかかって仕方ないでしょう。
そこで、今回の本題であるcolor-mix()関数が使えるというわけです!
本題
まずはcolor-mix()関数について。
color-mix() 関数記法は 2 つの 値を採り、指定された色空間の指定された量で混合した結果を返します。
https://developer.mozilla.org/ja/docs/Web/CSS/Reference/Values/color_value/color-mix
簡単に言えば、2つの色を混ぜて出力するということです。
記法は以下のようになっています。
color-mix(method, color1[ p1], color2[ p2])
methodは色補間に使用する色空間を指定しますが、これは自動入力で出てくるsrgbで問題ないようです。
color1とcolor2はそれぞれ混合する色、p1とp2はそれぞれのcolorのパーセンテージです。
詳細な解説はMDNのページをご覧ください。
https://developer.mozilla.org/ja/docs/Web/CSS/Reference/Values/color_value/color-mix
今回出力したい–mainColor: #ddd;、opacity: 0.7;を当てはめると、
background-color: color-mix(in srgb, var(--mainColor) 70%, transparent);
となります。p1・p2は片方を省略した場合は100%からもう片方を引いた値が割り振られるのでtransparent側の透明度を指定する必要はありません。
実際に指定したサンプルがこちらです。
See the Pen color-mix() by NP-Kanbara (@elmhgegi-the-solid) on CodePen.
CSS変数とcolor-mix()で指定した場合と、Sass関数rgba()で指定した場合で同じ結果を得られていることがわかりますね!
おわりに
CSS変数は取り回しの良さが魅力なので、こうして様々なパターンに対応できると嬉しいですね!
ではまた。




