5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

背景色から文字色を自動判定する方法

5
Last updated at Posted at 2026-03-27

背景色に最適な文字色を1行数式で自動判定!

UIを開発していると、こんな場面に出くわしたことはないでしょうか。

「このバッジの背景色、黄色にしたら文字が見えなくなった...」
「ユーザーが自由に色を選べるカラータグ、文字色はどうすれば?」

背景色が動的に変わるUI要素では、文字色を白にするか黒にするかの判断が常につきまといます。手動で1色ずつ設定するのは現実的ではありません。

実は、たった1行の数式でこの問題を解決できます。


背景色と文字色の見やすさが重要な理由

視認性がユーザー体験を左右する

Webサイトやアプリケーションにおいて、テキストの読みやすさはユーザー体験の根幹です。背景色と文字色のコントラストが不十分だと、以下のような問題が発生します。

  • 読み飛ばし: ユーザーが重要な情報を見落とす
  • 離脱率の上昇: 読みにくいサイトからはすぐに離れる
  • アクセシビリティの欠如: 色覚多様性を持つユーザーや高齢者にとって致命的

動的な背景色で問題は深刻化する

固定デザインであれば、デザイナーが1つずつ文字色を調整できます。しかし、以下のようなケースでは背景色が動的に変わるため、手動調整は不可能です。

  • カテゴリタグ・バッジ: ユーザーやシステムが色を自由に設定する
  • カラーテーマ: ダークモード/ライトモードの切り替え
  • データ可視化: ヒートマップやグラフの色分け
  • 管理画面: 会議タイプ、ステータス、優先度ラベルなど

こうした場面で必要なのは、背景色を入力として、最適な文字色を自動的に返す仕組みです。


NTSC輝度係数を使った自動判定の仕組み

1行の数式で解決する

背景色から文字色を自動判定する数式は、驚くほどシンプルです。

luminance = (0.299 × R + 0.587 × G + 0.114 × B) / 255

この計算結果(0〜1の範囲)が 0.5を超えれば明るい背景 → 黒い文字、0.5以下なら暗い背景 → 白い文字を選択します。

なぜ「0.299, 0.587, 0.114」なのか?

この3つの数値はNTSC加重係数と呼ばれ、1953年にアメリカのNTSCカラーテレビ規格で定義されました。後にITU-R BT.601として国際標準化されています。

単純にRGBを平均((R+G+B)/3)するのではなく、人間の目の感度に基づいて重み付けしています。

係数 理由
赤(R) 0.299(29.9%) 中程度の感度
緑(G) 0.587(58.7%) 最も敏感。同じ数値でも緑は明るく感じる
青(B) 0.114(11.4%) 最も鈍感。青は暗く感じやすい

例えば、純粋な緑 rgb(0, 255, 0) と純粋な青 rgb(0, 0, 255) はどちらもRGB値の1つが255ですが、人間の目には緑の方がはるかに明るく見えます。単純平均ではどちらも同じ85になってしまいますが、この加重平均なら緑=149.7、青=29.1と正しく差を反映できます。

実際の判定例

背景色 HEX R,G,B 輝度 判定
#ef4444 239, 68, 68 0.43 白文字
黄色 #f59e0b 245, 158, 11 0.67 黒文字
#3b82f6 59, 130, 246 0.44 白文字
#10b981 16, 185, 129 0.52 黒文字
#8b5cf6 139, 92, 246 0.44 白文字
グレー #6b7280 107, 114, 128 0.44 白文字

実際の導入方法とメリット

JavaScript / TypeScript での実装

最もよく使われるWeb実装です。HEXカラーコードを引数に取り、白か黒を返します。

function getContrastTextColor(hexColor: string): string {
  const hex = hexColor.replace('#', '');
  const r = parseInt(hex.substring(0, 2), 16);
  const g = parseInt(hex.substring(2, 4), 16);
  const b = parseInt(hex.substring(4, 6), 16);
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  return luminance > 0.5 ? '#1e293b' : '#ffffff';
}

使い方はシンプルです。

// バッジのスタイルに適用
const badgeStyle = {
  backgroundColor: userColor,
  color: getContrastTextColor(userColor),
};

Python での実装

バックエンドやデータ処理でも同じロジックが使えます。

def get_contrast_text_color(hex_color: str) -> str:
    hex_color = hex_color.lstrip('#')
    r = int(hex_color[0:2], 16)
    g = int(hex_color[2:4], 16)
    b = int(hex_color[4:6], 16)
    luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
    return '#1e293b' if luminance > 0.5 else '#ffffff'

CSS(カスタムプロパティ)での応用

CSS単体では動的計算が難しいですが、CSS変数とJavaScriptを組み合わせることで実現できます。

.badge {
  --bg-color: #ef4444;
  background-color: var(--bg-color);
  /* JavaScriptで動的に設定 */
  color: var(--text-color, #ffffff);
}
const badge = document.querySelector('.badge');
const bgColor = getComputedStyle(badge).getPropertyValue('--bg-color').trim();
badge.style.setProperty('--text-color', getContrastTextColor(bgColor));

利用シーンの具体例

この自動判定は以下のような場面で威力を発揮します。

  • タグ・バッジ: カテゴリラベル、ステータス表示、優先度マーク
  • カレンダー: イベントの色分け表示
  • ダッシュボード: KPIカードの背景色に応じた数値表示
  • チャート: グラフ上のデータラベル
  • 管理画面: ユーザーがカスタマイズ可能な色設定

BT.601 vs BT.709 vs WCAG

同じ目的で使われる規格が複数存在します。用途に応じて使い分けましょう。

規格 係数(R, G, B) 用途
BT.601(NTSC) 0.299, 0.587, 0.114 SD映像、一般的なWeb実装
BT.709 0.2126, 0.7152, 0.0722 HD映像、より正確な色再現
WCAG 2.0 sRGBガンマ補正後にBT.709 アクセシビリティ準拠

一般的なUI開発ではBT.601で十分です。WCAG準拠が求められる場合は、ガンマ補正を含むより厳密な計算が必要になります。

WCAG準拠にするなら

WCAGでは、コントラスト比を以下の式で計算します。

コントラスト比 = (L1 + 0.05) / (L2 + 0.05)

L1は明るい方、L2は暗い方の相対輝度です。通常テキストでは4.5:1以上(AA基準)、大きなテキストでは3:1以上が求められます。

厳密なアクセシビリティ対応が必要な場合は、BT.601の簡易計算ではなく、sRGBガンマ補正を含むWCAGの計算式を使いましょう。


まとめ

  • NTSC輝度係数 (0.299, 0.587, 0.114) を使えば、背景色から最適な文字色を1行で自動判定できる
  • この係数は1953年のカラーテレビ規格に由来し、人間の目の感度を反映している
  • JavaScript、Python、CSSなどどの言語でも数行で実装可能
  • より厳密なアクセシビリティ対応にはWCAGのコントラスト比計算を検討する

動的に色が変わるUI要素を扱う開発者にとって、この数式は知っておいて損のないテクニックです。たった1行で、デザインの品質とユーザー体験を確実に向上させることができます。

AIコーディングツールへの指示例

Claude CodeやGitHub Copilotなどのコーディングアシスタントに、この機能を実装させたい場合の指示例を紹介します。自分でコードを書かなくても、適切に指示すれば数秒で実装が完了します。

基本的な指示:

「背景色のHEXコードを受け取り、NTSC輝度係数(BT.601: 0.299, 0.587, 0.114)を使って文字色を白か黒か自動判定する関数を作って」

既存コードへの適用:

「このバッジコンポーネントの文字色を、背景色のluminanceから自動判定するようにして。BT.601の加重係数を使って、明るい背景なら暗い文字、暗い背景なら白文字にして」

より具体的な指示(プロジェクト全体への適用):

「プロジェクト内でユーザーが色を選択できるUI要素(タグ、バッジ、カテゴリラベル等)を全て洗い出して、文字色をNTSC輝度係数で自動判定するように統一して。共通ユーティリティ関数として切り出すこと」

WCAG準拠を求める場合:

「背景色と文字色のコントラスト比がWCAG 2.0のAA基準(4.5:1以上)を満たすように、文字色を自動選択する関数を実装して。sRGBガンマ補正を含むWCAGの相対輝度計算を使うこと」

ポイントは、「NTSC輝度係数」「BT.601」「0.299, 0.587, 0.114」 といったキーワードを指示に含めることです。AIはこれらの用語から正確な数式と実装パターンを認識し、適切なコードを生成します。逆に「背景色に合わせて文字色を変えて」だけだと、単純なif文や不正確な計算式が生成される可能性があります。


参考資料

5
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?