世界を動かす技術を、日本語で。

CSSでブラウザに対比色を選ばせる方法

2025年5月18日原文(webkit.org)

概要

  • contrast-color()関数 により、CSSで自動的に最適なテキスト色(黒または白)を選択できる機能を紹介。
  • 背景色の変化に応じて、テキスト色を手動で管理する手間を大幅に削減可能。
  • 現在の実装では WCAG 2 アルゴリズムが使われており、必ずしも知覚的に最適なコントラストを保証しない。
  • APCA など新しいアルゴリズムの導入が検討されており、将来的な改善が期待される。
  • アクセシビリティ確保には色選びやフォントサイズ・太さの配慮、prefers-contrastメディアクエリの活用が重要。

contrast-color()関数による自動コントラスト色選択

  • CSSの contrast-color()関数 を使うことで、指定した背景色に対して 黒または白 のうちコントラストが高い方を自動選択することが可能。
  • 例:color: contrast-color(purple);と記述することで、purple背景に対し自動的に黒か白のテキスト色を割り当てる提案。
  • ボタンの背景色を変数--button-colorで管理し、テキスト色はcontrast-color(var(--button-color))で自動決定することができる確認。
  • ボタンのホバー時の色変化も、Relative Color Syntax(例:oklch)と組み合わせて一つの変数から複数の配色を管理することが可能。
  • こうした仕組みにより、 大規模プロジェクト でも色管理の手間を削減し、コントラスト問題による可読性低下を防ぐことができる提案。

contrast-color()の実装と制限

  • 現時点(Safari Technology Preview等)では WCAG 2 アルゴリズムに基づいてコントラスト判定を実施すること。
  • WCAG 2 は法的にも標準とされているが、知覚的なコントラストと数学的なコントラストが一致しない場合がある指摘。
  • 例えば、#317CFFの青背景では、WCAG 2では黒テキストが推奨されるが、実際には白テキストの方が見やすいと感じる場合がある説明。
  • APCA(Accessible Perceptual Contrast Algorithm) などの新アルゴリズムがWCAG 3で検討されており、より人間の知覚に近いコントラスト判定が可能となる見込み。
  • contrast-color()関数のアルゴリズムは将来的に切り替えが可能であり、CSS標準でも今後のアップデートが予定されている確認。

コントラストのアクセシビリティと実践的配慮

  • contrast-color()関数の利用だけでは、 十分なコントラスト やアクセシビリティを保証できない警告。
  • 中間色(ミッドトーン)では、黒・白どちらを選んでも十分なコントラストが得られない場合がある指摘。
  • フォントサイズやウェイト(太さ)によっても必要なコントラスト基準は変化するため、デザイン時に総合的に配慮することが重要。
  • prefers-contrastメディアクエリ を用いることで、ユーザーが高コントラストを求めている場合に代替配色を提供することができる提案。
  • APCAスコアはLc値(Lightness contrast)で示され、フォントサイズや太さに応じて適切な閾値が設けられているため、より柔軟なアクセシビリティ対応が可能。

実践例:ブランドカラーとアクセシビリティ両立

  • 例として、明るい緑(#2DAD4E)をブランドカラーにしたボタンデザインを考える場合、APCAスコアやprefers-contrastメディアクエリを活用して配色を調整することが推奨される提案。
  • フォントサイズ24px・ウェイト400以上なら白テキストでも十分なコントラストが得られるが、より小さいサイズや細いフォントでは色を変更することが必要。
  • prefers-contrast: moreが指定された場合には、ダークグリーンやライトグリーンなど、よりコントラストの高い色に切り替えることで、幅広いユーザーのアクセシビリティニーズに対応することができる確認。
  • 変数で色を管理することで、状況に応じた配色の切り替えが容易となり、contrast-color()の活用でテキスト色の自動化も実現できる提案。
  • アクセシビリティは単なる基準のクリアではなく、実際のユーザー体験を重視した柔軟な設計が求められることを強調。

参考:主要CSS記述例

:root {
  --button-color: purple;
  --hover-color: oklch(from var(--button-color) calc(l + .2) c h);
}
button {
  background-color: var(--button-color);
  color: contrast-color(var(--button-color));
  text-box: cap alphabetic; /* テキストの垂直中央揃え */
}
button:hover {
  background-color: var(--hover-color);
  color: contrast-color(var(--hover-color));
}
@media (prefers-contrast: more) {
  /* より高コントラストな配色に切り替え */
}

まとめ

  • contrast-color()関数は、 色管理の効率化アクセシビリティ向上 に大きく貢献する新機能。
  • ただし、現状のアルゴリズムや色選びだけに頼らず、デザイナーや開発者が 実際の可読性やユーザー体験 を重視して調整・確認することが不可欠。
  • 新しいコントラストアルゴリズムやCSS機能の進化を積極的に取り入れ、 柔軟かつ実用的なアクセシビリティ対応 を心がけることが重要。

Hackerたちの意見

大きなプロジェクトで大規模なチームが関わると、こういった細かい部分をしっかり管理するのが本当に難しくなるよね。突然、暗いボタンに読めない黒い文字があって、ユーザーがどうすればいいかわからなくなっちゃう。大きなプロジェクトが出る前に、誰かボタンをチェックしてくれないかな?それか、暗いボタンには絶対に黒い文字を使わないってルールを作って、全てのチームメンバーに伝えるべきだよね。知覚的コントラストと数学的コントラストについて読むのは面白いね。そんなこと知らなかったよ。これを自分のワークフローに取り入れてみるつもり。

APCAについて調べてみるといいよ。APCAアルゴリズムを使って知覚的コントラストの計算ができるから。

大きなプロジェクトが出荷される前にボタンを確認する人はいないの? もちろんできるけど、そうするとリリース前の回帰テストサイクルが数週間や数ヶ月になることがあるんだ。「大きなプロジェクト」には簡単に数千のボタン(それ以上も!)が含まれていて、その多くは特定の設定が有効になっているときや、複雑なワークフローの中で特定のオプションが選ばれたときにしか見えないんだよ。

lchを使えば、これに近いことができる方法があるよ: --text: lch(from var(--bg) calc((49.44 - l) * infinity) 0 0); 参照: https://til.jakelazaroff.com/css/swap-between-black-and-whit...

こんなコールバックスタイルのCSS関数は見たことないよ。パラメータを変更できるのが面白いね!これ以外にも例はあるのかな、それともlchだけの特別なもの?

こんな感じのワークアラウンドについて、lea verouの良い記事があるよ。https://lea.verou.me/blog/2024/contrast-color/

LCHは素晴らしいけど、OKLCHはさらにいいよ!https://evilmartians.com/chronicles/oklch-in-css-why-quit-rg... この話題に関してこの文章が私の視点を劇的に変えたと言えるよ。本当に素晴らしいツールだ。デザイナーの友達が全くOKLCHを知らなかったことに驚いたし、これは全く新しい問題を解決してくれる。

コントラストの色をブラウザのベンダーが決めるべきだとはまだ納得できないな。いつも正しいとも限らないし、予測もできないよね。これが全てのブラウザで決定的な標準になるのかな?この機能は、デザインフェーズでUXチームを助けるためのツールって感じがする。

参照: https://news.ycombinator.com/item?id=44015980、APCAのボタンの例についての混乱から不正確な部分を取り除くと、100%正しいってことが少しクリアになるよね。でも、一貫性はない。例えば、L* 50の背景があって、白か黒の前景がほぼ同じように機能する場合、そこでは美的原則が関わってくる。これを明確にして、100%信頼できるようにするためには、コントラストKと背景色Cが与えられた場合、暗い色と明るい色の両方が利用可能なら、Cを見て、L*が>= 60なら明るい方を選ぶ。そうすれば、100%正しくて一貫性がある。

これが全てのブラウザで決定的な標準になるのかな?記事には、標準が使用する計算を指定していると書いてあるよ。

ここで「選ぶ」って言葉は変だね。色を計算するアルゴリズムがあるんだ。

最低限、ライトテーマとダークテーマのために、擬似クラスのアクティブ、フォーカス、ホバー、リンク、訪問済み、それらの様々な組み合わせに対して良い色を知っておくといいよね。さらに、マテリアルUIは無効、前、後も追加してるし。

Hacker Newsで議論の続きを見る