Last updated on

color-mix は in oklch を基本にする──opacity との違いと色空間の選び方

  • CSS
  • color-mix
  • OKLCH
  • デザイントークン
  • SCSS
  • Sass

オーバーレイやドロワーの背面を暗くしたいとき、opacity で一括に薄くすると、子要素やテキストまで半透明になる落とし穴があります。背景だけにアルファを持たせるなら color-mix() が定石のひとつです。ここでは in oklch を既定に寄せる理由と、例外として in srgb を選ぶ場面を整理します。

ブラウザ対応はプロジェクトのサポート方針に合わせて確認してください(color-mix や OKLCH 補間はモダンブラウザ前提になりやすいです)。


背景だけ薄くしたいのに、文字まで透ける

次のように書くと簡単ですが、UI では要件とズレやすいです。

.example {
  background-color: var(--color-black);
  opacity: 0.6;
}

opacityその要素の描画全体に効きます。背景だけでなく、子要素やテキストもまとめて半透明になります。「背面は暗くしたいが、前面の文字ははっきり読ませたい」という要件では別の手段に切り替えるのが安全です。


解決策: 背景色の側に「透明度」を持たせる

color-mix() を使うと、背景色が指定比率の黒と透明の中間になり、子やテキストの不透明度は変わりません。

.example {
  background-color: color-mix(in oklch, var(--color-black) 60%, transparent);
}

color-mix の第 1 引数はどの色空間の座標で混ぜるか(補間のルール)を指定します。ここでは in oklch としています。


Sass の rgba() でも「子は透けない」は作れる

要素全体の opacity ではなく、background-color ひとつの色にアルファを載せるという意味では、Sass では昔から次のような書き方がよく使われます。

.example {
  // $color-black はビルド時に解ける Sass の色(変数やトークンから map-get など)
  background-color: rgba($color-black, 0.6);
}

rgba(色, 不透明度)そのプロパティに出す色の A チャンネルだけを変えるので、子要素やテキストの不透明度はそのままです。opacity の落とし穴は避けられます。

ただし次の点は押さえておくとよいです。

  • ビルド時に Sass が解ける色向きです。background-color: rgba(var(--color-black), 0.6) のように CSS 変数だけを渡す形は、チャンネル分解ができずそのままでは通りません(rgb(from var(--token) r g b / 0.6)color-mix など、ブラウザ側の色構文と組み合わせる必要があります)。
  • コンパイル結果は CSS の rgba() / rgb(... / ...) になり、どの色空間で黒と透明の「中間」を取るかcolor-mixin oklch のように選べません。知覚的な混ぜ方まで揃えたい場合は、素の CSS で color-mix を使う方が役割がはっきりします。
  • モジュール系の API では、同種の操作を color.change$alpha を変える)で表現することもあります。慣れ親しんだ rgba($color, $alpha) とセットで覚えておけば十分なことが多いです。

公式の色まわりの API 一覧は Sass sass:color モジュール を参照してください。


なぜ「色空間」を選ぶのか

color-mix(in <空間>, A, B)<空間> は、2 色の「中間」をどのルールで取るかを決めます。同じ比率でも、in srgbin oklch では結果の色が変わり得ます。色相が大きく変わる組み合わせや、グラデーションの途中色で差が出やすいです。


なぜ in oklch を基本にしたいのか

  1. 知覚的に素直な中間色 … sRGB 上で直線補間すると、途中が濁ったり暗すぎたりと、目で見た印象とズレやすいことがあります。OKLCH(OK 色空間の円柱表現)は、明るさ・鮮やかさ・色相を分けて扱いやすく、UI での混色やグラデーションが自然になりやすいです。
  2. デザイントークンとの相性--color-* 同士の混合や、トークンと transparent のオーバーレイは案件で繰り返し使います。補間の空間を oklch に揃えておくと、案件をまたいで見た目のブレを減らしやすいです。
  3. 色相まわりの補間 … 2 色の間で色相が回るとき、LCH 系は色相チャンネル上の取り方が明確で、意図しない「遠回り」の中間色を避けやすいです(厳密な挙動は仕様とブラウザ実装に合わせて検証してください)。
  4. モダンブラウザ前提なら実用十分 … 対象ブラウザが極端に古い場合は、in srgb や別のフォールバックを検討します。採用可否はプロジェクトのサポート方針が正です。

oklab との違いは何か

どちらも OK 色空間系で、**「人間の目に近い均等さ」**という方向性は近いです。円柱座標で色相を明示的に扱うなら oklch、直交座標で足りるなら oklab も選択肢です。チームで表記を分かれさせないなら、どちらかに統一するのがおすすめです。本稿では oklch に寄せる前提で書いています。


いつ in srgb を選ぶか

次のようなときは in srgb が合理的です。

  • 意図的に、従来のディスプレイ RGB 上のにじみや中間色に合わせたいとき。
  • ベンダーやデザインガイドが「補間は sRGB」と固定しているとき。
  • サポート対象のブラウザが、OKLCH 補間の利用に不安があるとき。

既存コードで in srgb が使われている箇所を oklch に変える場合は、スクリーンショットやデザインツールと見比べて差分を確認してから置き換えるのが安全です。黒と透明のような無彩色同士では差が小さいことも多いですが、保証ではありません。


まとめ

  • opacity は要素全体に効くので、「背景だけ薄く」には向かないことが多い。
  • 背景だけ薄くしたいなら、background-color にアルファ相当を持たせる(例: color-mix、または Sass の rgba($color, $alpha) などビルド時に解ける色なら従来どおり)。
  • color-mix では in oklch を基本にすると、知覚的に自然でトークン運用もしやすい。
  • 意図的な sRGB 再現やブラウザ方針に応じて in srgb を例外として使う。