見出し画像

CSS Color-mix Tips ~2024 spring~

BLUE B NOSEでは、色味をコントロールするテクニックとして、Color-mix関数を積極的に取り入れています。記述が長くなりがちなColor-mix関数、どう使えば良いかイマイチ分かりにくい同関数の多少便利そうな使い方をいくつか発見したので、この機会にちょこっとご紹介します。

先日4月1日に配信したSubstackの記事の中で

新しい色空間や、Color-mix関数について簡単に取り上げましたが、Color-mix関数についてはまだまだご紹介できそうなテクニック、小ネタがいくつかありますので、2024年春のTipsとして改めてまとめてみましょう。我々の細やかな知見が、少しでも役に立てば良いのですが.....。


そもそも、Color-mix関数って?

近年使えるようになったColor-mix関数ですが、まずは定義やサポート状況を確認してみましょう。
MDN Web Docsによると、基本的な書き方は

color-mix(method, color1[ p1], color2[ p2])

上記リンクより引用。
color1とcolor2を、methodに指定した色空間の中で混色します。

上記の MDN Web Docsでも、Can I use

でも、現在は主要なブラウザでほぼサポートしているようなので、

srgb, srgb-linear, lab, oklab, xyz, xyz-d50, xyz-d65, lch, oklch

といった新しい色空間での混色も、気楽に活用できます。
例えば、

body {
  background-color: color-mix(in oklab, #333, #fff);
}

とすると、#333と#fffを50%ずつ混色した結果をbodyの背景色に指定します。

body {
  background-color: color-mix(in oklab, #333 70%, #fff);
}

とすると、#333が70%、#fffが30%の割合、

body {
  background-color: color-mix(in oklab, #333, #fff 70%);
}

とすると、#333が30%、#fffが70%の割合、比率を指定しない場合はどちらも50%の混色となります。

どのmethodを指定するかは好みの問題ですが、精度や制御を考慮するとoklabが無難かなぁというのが現時点の経験則です。
記述は若干長くなってしまいますが、デザインセンスが皆無でもそんなに大きく間違った配色にはなりにくいので、デザインセンスに自信がない方こそ、どんどん使った方がいい書き方だと考えています。

Color-mix関数は何がどう便利なのか?

具体的には以下をご覧いただきましょう。

ほぼ上で完結しているのですが、諸々補足していくと"color-mix関数"で検索してもあまり出てこないtipsとして、"transparent"を混色してopacityと似た挙動を実現する、という手法があります。

a:hover {
  opacity: .7;
}

の方が記述は短いですが、

a:hover{
  color:color-mix(in oklab, transparent, currentColor 70%);
}

(transparentを30%混色、currentColorを透明度70%とする)としても、テキストカラーの挙動はほぼ同じことができます。
color-mixを使用する方が記述は長くなりますが、opacityを使ってしまうと影響範囲や挙動が大味になり過ぎてしまい、対象範囲を絞った上で一部だけ透明化させたり、色を濃くしたり、色を白くしたりといった挙動をしたい場合は、color-mixの方が便利です。

画像とテキストでhoverのアクションを分けたい、テキストだけ透明化したいといった時は、transparentを混色する手法がオススメです。

また、白系や黒系の無彩色を別途設定しておけば、

a:hover{
  color:color-mix(in oklab, #fff, currentColor 70%);
}

で薄い色、

a:hover{
  color:color-mix(in oklab, #000, currentColor 70%);
}

で濃い色が一定の割合で生成可能です。自然な混色で濃淡のグラデーションも生成できるので、デザインセンスがなくても問題ありません。

カスタムプロパティも(currentColorも)混色できる

2色を混ぜるだけならSassだけでも可能ですが、Sassではカスタムプロパティの混色はできないので、カスタムプロパティで色を設定している場合は、color-mixが便利です。
特に、

@media (prefers-color-scheme: dark)

やjsを用いて".is-dark"等のclassの付け外しでダークモードで用いる色を制御している場合、Sassだけでは完結できない上に、色味自体が逆転していることもあり、カスタムプロパティを上手に駆使して混色可能なcolor-mixが活躍しやすい環境なのではと思っています。

例えば上記では、色の濃淡を制御するために特定の色を指定していましたが、

--text-body: #333;
--bg: #fff;

@media (prefers-color-scheme: dark){
  --text-body: #fff;
  --bg: #333;
}

と完全に逆転させた場合でも、

a:hover{
  color:color-mix(in oklab, var(--bg), currentColor 70%);
}

で背景色との混色や

a:hover{
  color:color-mix(in oklab, var(--text-body), currentColor 70%);
}

でテキストとの混色で、一定のバランスを保って色の濃淡をコントロールすることが可能です。

Sassを使っている場合は、混ぜる色を

#{rgba(hoge), .7}

のようにしてあげれば、アルファ値を持った色を混ぜるという手法も可能です。ただこの場合、カスタムプロパティと同様の恩恵は受けられないので、ダークモード用の混色も用意する必要があるため、その点は要注意です。"#{}"で囲むのも忘れがちなので気をつけて。

ダークモード x ghostボタンの場合

ボタン自体には背景色がなく、外形線とテキストカラーのみで構成されるghostボタン。
どんな背景色が来るかが分からないので、hover時のスタイリングや、focusやactiveでのスタイリングをどうするか、迷いますよね?

おまけにダークモードで色が変化する要素も乗っかってくると、色味のコントロールをどうすべきか、ややこしさに拍車がかかってしまいますが、以下のような設定でcolor-mixを用いれば、割と取り回しもしやすく、視認性も確保したスタイリングができるかと思います。

ghostボタンを配置する親要素に

.u-bg-blue {
  background-color: var(--bg-blue);
  color: var(--bg);
}

と背景色を設定しつつ、テキストカラーには通常の背景色を指定します。ghostボタン自体には、

.c-ghost-btn{
  border: solid 1px currentColor; 
  color: currentColor; 
  background-color: transparent;
}

としておくと、親要素のcolor設定をcurrentColorとして適用してくれます。
その上で、

.c-ghost-btn:hover{
  background-color: color-mix(
    in oklab,
    var(--text),
    var(--bg-blue) 70%
  );
  color: color-mix(in oklab, transparent, var(--text) 70%);
}

のようにすると、親要素の背景色とベースのテキストカラーを混色した背景色を設定しつつ、テキストカラー自体はベースのテキストカラーを透明化した色を指定したり、

.c-ghost-btn:hover{
  background-color: var(--bg);
  color: color-mix(in oklab, transparent, var(--text) 70%);
}

で、背景色とテキストカラーを入れ替えたスタイリングにしてみるのはいかがでしょう?

あとは混色する色の指定さえ変更すれば、そんなにおかしい色合いにはならないので割と使い回しもしやすい設定なのではと思っています。

ハンバーガーメニューの3本線など、backgrond-colorで色を指定していてcurrentColor等での連動も組み込んでいる場合は、更にcolor-mixの恩恵を受けやすいような気はします。ただし、親要素のcolor指定はお忘れなく。

Color-mixに任せれば、デザインセンスは不要

配色の細かいことはよく分からなくても、Color-mixやMaterial Designの環境を用いれば、コントラスト比をしっかり保った上でのダークモード対応等は、センスがなくてもできる時代がやって来ました。

transparentやcurrentColorも混色できるし、色の濃淡も機械任せにコントロールできるcolor-mix関数、多少記述は長いですが、もっと色んなところで積極的に使ってみませんか?

こんな使い方もあるよ、とご存じの方がいらっしゃいましたら、その知見もぜひ教えてください。

今後も「お役立ち情報」をお届けします

BLUE B NOSEでは今後も、経験を通じて得たナレッジやtipsの共有、独自視点でのお役立ち情報をお届けします。HP上でもコンテンツを発信する予定なので、もしよろしければ当アカウントのフォローや、HPのチェックもお願いします。


この記事が気に入ったらサポートをしてみませんか?