テック技報最新号へ →
CSS

contrast-color() でボタンの文字色を背景に合わせて自動で白か黒にする

背景色をカスタムプロパティに入れ、color: contrast-color(var(--bg)) と書くと、ブラウザがその背景で読みやすい方(白か黒)を選んでくれる。

@bkarishma360 · 投稿 2026-11-02

どんな時に使う?

  • ユーザーやCMSがボタン・タグ・バッジの色を自由に選べて、文字色を色ごとに決めておけないとき。
  • テーマ色を変えるたびに「この色なら文字は白?黒?」を手で調整したくないとき。

コード

css
.button {
  --bg: hsl(55 88% 52%); /* 黄色なら黒文字が選ばれる */
  background: var(--bg);
  color: contrast-color(var(--bg));
}

/* 色違いはカスタムプロパティを差し替えるだけ */
.button.danger { --bg: hsl(0 75% 45%); } /* 濃い赤なら白文字 */

注意点・対応状況

  • 今のところ返すのは白か黒の2択。ブランド色の文字にしたい場合は使えない。
  • 「コントラストが高い方」を選ぶだけで、必ず WCAG の基準を満たすとは限らない。中間的な明るさの背景では白でも黒でも足りないことがあるので、主要な色は確認しておく。
  • 比較的新しい関数なので、未対応ブラウザ向けに先に普通の color を書いておくか、@supports (color: contrast-color(red)) で分ける。対応状況は Can I use で確認する。
  • 同じ関数を画像の alt テキスト対策に使う例は 画像が読み込めない時の alt テキストを contrast-color() で読めるようにする。

追記(2026-11-10): color-mix() で背景色に寄せて柔らかくする

真っ白・真っ黒の文字が強すぎてブランドの雰囲気に合わないときは、contrast-color() の結果を背景色と少し混ぜる。コントラストは下がるが、背景になじんだ文字色になる。

css
.button {
  --bg: oklch(65% 0.18 250);
  background: var(--bg);
  /* 白か黒を 80%、背景色を 20% 混ぜる */
  color: color-mix(in oklch, contrast-color(var(--bg)) 80%, var(--bg));
}

混ぜる割合を増やすほど読みにくくなるので、混ぜた後の色で WCAG のコントラスト比を確認しておく。ブランド色の濃淡の作り方は color-mix() で1つのブランド色からホバー用の濃い色・薄い背景色を作る を参照。出典: @gkurttech(2026-11-09)

出典

X の元の投稿を開く