N2
NanToo
CSS color-mix() と OKLCH — ブランドカラーから自動でホバー/無効色を導く設計
GDESIGN
デザイン7 分で読める

CSS color-mix() と OKLCH — ブランドカラーから自動でホバー/無効色を導く設計

「ブランドカラーは #2563eb です。では、ホバー時は? アクティブ時は? 無効時は? ボーダー用のもっと薄い色は?」— 従来はデザイナーが手作業で微調整し、9〜12 段階のパレットを作っていました。しかし CSS Color Module Level 5color-mix() 関数と OKLCH 色空間を組み合わせれば、ブランドカラー1つから数式で派生色を自動生成できます。2024 年に主要ブラウザでサポートされ、Tailwind CSS v4 でも標準採用されました。

#CSS#color-mix#OKLCH#デザインシステム#色空間

色空間の歴史 — RGB から OKLCH まで

Web における色表現の歴史を整理すると、人間の知覚との一致度が徐々に改善されてきたのが分かります。

色空間策定特徴
RGB / sRGB1996ディスプレイ表示規格、R/G/B の加法混色
HSL / HSV1978色相/彩度/明度に分離、sRGB の単純変換
CIE 1931 XYZ1931人間の視覚特性を3原色に紐付けた基礎
CIELAB (L*a*b*)1976知覚均等 (ΔE が視覚差と比例) を目指した
OKLab / OKLCH2020CIELAB の欠点を修正、現代Webで最適解

HSL の限界: hsl(60, 100%, 50%) の黄色と hsl(240, 100%, 50%) の青は、数値上「同じ明度」ですが実際には黄色のほうが圧倒的に明るく見えます。これは sRGB の R/G/B 加重が人間の知覚 (視感度曲線) と一致しないため。

OKLCH の仕組み — Björn Ottosson の2020年論文

OKLab は 2020 年に Björn Ottosson が発表した "A perceptual color space for image processing" で提案された色空間です。CIELAB の弱点 (青色域での知覚ずれ) を修正し、現代のディスプレイ(広色域 P3)にも対応。

OKLCH は OKLab の極座標表現 (円筒座標):

  • L (Lightness): 0〜1、知覚上の明度
  • C (Chroma): 0〜0.4 程度、彩度 (最大値は色相で異なる)
  • H (Hue): 0〜360 度、色相
/* CSS 構文 */
oklch(59.4% 0.22 263)   /* Tailwind blue-500 相当 */
oklch(0.594 0.22 263)   /* 小数表記 */

HSL と違い、同じ L 値なら違う色相でも知覚明度がほぼ等しくなるのが最大の利点。デザインシステムで「この色と同じ明るさの別の色が欲しい」というニーズに応えられます。

color-mix() の構文

CSS Color Module Level 5 の color-mix() は、2つの色を指定した色空間・比率で混ぜる関数です。

color-mix(in <色空間>, <色1> <比率>, <色2> <比率>)

/* 基本 */
color-mix(in srgb, red 50%, blue)     /* sRGB でR-Bの中間 */

/* OKLCH 空間で混色 */
color-mix(in oklch, red, blue)        /* 50:50 の均等混合 */
color-mix(in oklch, #2563eb 80%, white)  /* 青を20%薄めた色 */
color-mix(in oklch, #2563eb, black 30%)  /* 青に30%黒を足した色 */

補間色空間の指定が重要です。同じ「red と blue の中間色」でも:

  • in srgb: 紫色 (R/B の単純平均)
  • in oklch: 赤→灰色→青の経路 (知覚的に自然)
  • in hsl: 色相が近道を通るのでダーティな中間色

ブランドカラーのトーン展開には in oklch が推奨されます。

ブランドカラーから派生色を自動生成するパターン

単一ブランドカラー --brand: #2563eb から、以下を自動生成できます。

:root {
  --brand: #2563eb;

  /* インタラクション状態 */
  --brand-hover:    color-mix(in oklch, var(--brand), white 15%);
  --brand-active:   color-mix(in oklch, var(--brand), black 15%);
  --brand-disabled: color-mix(in oklch, var(--brand), transparent 60%);

  /* ボーダー用の薄い色 */
  --brand-border:   color-mix(in oklch, var(--brand), white 70%);

  /* 背景用の超薄い色 (カード背景等) */
  --brand-bg:       color-mix(in oklch, var(--brand), white 92%);

  /* フォーカスリング */
  --brand-focus:    color-mix(in oklch, var(--brand), transparent 70%);
}

.button {
  background: var(--brand);
  border: 1px solid var(--brand-border);
}
.button:hover { background: var(--brand-hover); }
.button:active { background: var(--brand-active); }
.button:disabled { background: var(--brand-disabled); }

この仕組みなら、ブランドカラーを赤に変えるだけで、すべての派生色が追従します。デザイントークンを変えるコストが劇的に下がります。

ライトモード・ダークモードの自動化

ダークモード対応も color-mix() で大幅に簡潔化できます。

:root {
  --text: #1f2937;
  --bg:   #ffffff;
  --accent: #2563eb;
}

[data-theme="dark"] {
  --text: #e5e7eb;
  --bg:   #111827;
  /* アクセント色は明度を反転気味に */
  --accent: color-mix(in oklch, #60a5fa, transparent 0%);
}

/* 共通: 派生色は color-mix で自動追従 */
.card {
  background: color-mix(in oklch, var(--bg), var(--accent) 5%);
  border-color: color-mix(in oklch, var(--text), transparent 85%);
}

従来は「ライト用」「ダーク用」の色を全ペアで定義していましたが、基本色 3〜5 個を ライト/ダークで指定すれば、派生色は自動で意味が保たれるのが特徴です。

ブラウザ対応 (2025年現在)

  • Chrome/Edge: 111+ (2023年3月〜) で OKLCH と color-mix() 対応
  • Safari: 16.2+ (2022年12月〜)
  • Firefox: 113+ (2023年5月〜)
  • Samsung Internet / iOS Safari: 16+ で対応

2026年4月現在、モダンブラウザのシェア 97%+ が対応済み。IE11 や古い Edge Legacy を切ったプロジェクトなら、プリプロセッサなしで直接 CSS に書けます。

フォールバック戦略:

:root {
  --brand-hover: #3b7ced;  /* 事前計算したフォールバック */
  --brand-hover: color-mix(in oklch, #2563eb, white 15%);  /* 上書き */
}

Tailwind CSS v4 での採用

Tailwind CSS v4 (2024年12月正式版) は、色システムをOKLCH ベースに全面刷新しました。

  • 全プリセットカラーが OKLCH で定義 (例: blue-500 = oklch(62.8% 0.188 259.8))
  • Arbitrary values で bg-[color-mix(in_oklch,red,blue)] も可
  • カスタムカラーのトーン展開が数式で完結
  • 広色域 (P3) モニター対応

従来 v3 の HSL ベースパレットと比べ、階調がより知覚均等になり、特に50/100/200... 900/950 の明度階段が自然になったと評価されています。

色彩設計のベストプラクティス

  1. ブランドカラーは OKLCH で定義 (あるいは HEX から変換ツールで算出)
  2. 派生色は color-mix(in oklch, ...) で数式生成
  3. 同じ L 値をキープしてシリーズを作る (知覚明度が揃う)
  4. アクセシビリティ: WCAG コントラスト比 4.5:1 以上を WCAG チェッカー で検証
  5. ライト/ダークは基本色のみ切替、派生色は color-mix で自動追従
  6. 旧ブラウザ向けに静的フォールバック値を前方宣言
  7. デザイントークンは CSS Variables + セマンティック命名 (--color-primary よりも --brand-hover, --text-muted 等)

まとめ

  • OKLCH は CIELAB を改善した知覚均等色空間 (Ottosson, 2020)
  • color-mix() は CSS Color Module Level 5 の混色関数
  • in oklch で補間すると知覚的に自然な中間色
  • ブランドカラー1つから派生色(ホバー/アクティブ/無効/ボーダー) を自動生成可能
  • ライト/ダーク切替は基本色のみで、派生色は自動追従
  • モダンブラウザ (Chrome 111+, Safari 16.2+, Firefox 113+) で対応
  • Tailwind CSS v4 が OKLCH ベースを標準採用

参考文献・ソース

記事作成に関する注記

本記事は AI(大規模言語モデル)を編集補助として活用して作成しています。 公開前に編集者が内容を確認していますが、事実誤認・仕様の解釈ミス・最新情報との齟齬が含まれる可能性があります。 重要な判断を行う際は、本文中の一次ソースや公式ドキュメントを必ずご自身でご確認ください。 誤りにお気づきの場合は、お問い合わせフォームよりご連絡いただけると助かります。

🔧 関連ツール

📚 関連記事