color-mix() で1つのブランド色からホバー用の濃い色・薄い背景色を作る
color-mix(in oklch, var(--brand), black 20%) で濃い色、transparent と混ぜて薄い色を作れば、--brand を1か所変えるだけで派生色がすべて追従する。
どんな時に使う?
ボタンのホバー色、押下時の色、選択中の行の薄い背景など、ブランド色の「濃い版・薄い版」を何色も用意しているとき。hex を1色ずつベタ書きすると、テーマ色を変えた時に派生色だけ古いまま残りがち。color-mix() で元の色から計算しておけば、トークンが1つで済む。
コード
css
:root {
--brand: oklch(0.62 0.19 255);
/* 黒を 20% 混ぜて濃く(ホバー) */
--brand-hover: color-mix(in oklch, var(--brand), black 20%);
/* 黒を 35% で、さらに濃く(押下) */
--brand-active: color-mix(in oklch, var(--brand), black 35%);
/* 白を混ぜて明るく(不透明なまま淡い色) */
--brand-light: color-mix(in oklch, var(--brand), white 80%);
/* 透明と混ぜて薄く(下地が透ける淡い背景) */
--brand-soft: color-mix(in oklch, var(--brand) 18%, transparent);
}
.button { background: var(--brand); }
.button:hover { background: var(--brand-hover); }
.button:active { background: var(--brand-active); }
.row[aria-selected="true"] { background: var(--brand-soft); }- 書き方は
color-mix(in <色空間>, 色A 割合, 色B 割合)。割合を片方だけ書くと、もう片方は残り(100% − 指定)になる。var(--brand), black 20%は「ブランド 80% + 黒 20%」。 - 色空間は
in oklchかin oklabにすると、sRGB で混ぜた時より濁りにくく、明るさの変化も均一に感じやすい(混ぜ方の違いは グラデーションに in oklch を付けて、色の途中が灰色に濁らないようにする と同じ考え方)。 whiteを混ぜた淡い色は不透明、transparentを混ぜた淡い色は半透明。背景の上に重ねる場所では前者、下地を透かしたい場所では後者を使い分ける。
注意点・対応状況
color-mix()は Chrome / Edge 111+、Safari 16.2+、Firefox 113+ で、Baseline Widely available。- 透明度だけ変えたい場合は、より短く書ける
alpha()もある(alpha() でカラートークンの薄い背景色を作る)。ただしalpha()は 2026-09 に揃ったばかりなので、古い環境ではcolor-mix(..., transparent)が保険になる。 - 黒を混ぜた濃い色は、元の色によっては彩度が落ちてくすむ。気になる時は相対カラー構文で明るさだけ下げる(例:
oklch(from var(--brand) calc(l - 0.1) c h))方法もある。 - ダークテーマでは「ホバーで濃く」が逆に見えにくくなることがある。テーマごとに
black/whiteを入れ替えるか、light-dark()と組み合わせて調整する。 - 文字色とのコントラストは、混ぜた後の実際の色で確認すること。
出典
- @gkurttech(2026-11-07、CSS tip)