文字色と背景色の差が小さいと、読める人と読めない人が分かれる。
この差はコントラスト比という数値で表され、計算式が決まっているため感覚ではなく数字で判断できる。
ここでは、追加のツールを入れずにブラウザーだけで単色背景の候補を調べる方法と、判定の基準を整理する。
実測表は2026年9月20日の旧コードによる記録であり、掲載コードは2026年10月2日に祖先の透明度・背景画像と固定配置の扱いを修正した。
基準は2つに分かれる
ここで扱うのはWCAG 2.2の達成基準1.4.3(レベルAA)にある、文字の最低コントラストです。下限は文字の大きさと太さで変わります。
| 文字の条件 | 求められる比 | 呼び方 |
|---|---|---|
| 通常の文字 | 4.5対1以上 | 小さい文字の基準 |
| 24px以上 | 3対1以上 | 大きい文字の基準 |
| 約18.667px以上かつ太字 | 3対1以上 | 大きい文字の基準 |
同じ色の組み合わせでも、小さい文字では足りず、大きい見出しでは足りるという状態が起こる。
そのため、ページ全体を1つの値で判断できない。
1か所だけ測る
気になる箇所が決まっているなら、Chromeの開発者ツールで確認できます。次はChromeでの手順です。
- 対象の文字を右クリックして検証を選ぶ
- スタイルの欄でcolorの色見本をクリックする
- 背景色を判定できる場合、開いた色の画面でコントラスト比を確認する
比が表示されない箇所を合格と判断しないでください。背景画像などがある場合は背景条件を個別に確認します。操作箇所はChromeの公式説明でも確認できます。
色の組み合わせだけを先に決めたいときは、カラーコントラスト判定に文字色と背景色を入れる方法もある。
入力した2色の確認と、実ページでの表示確認は分けて行います。候補色を採用したら、実際の背景・文字サイズ・操作状態でも確認してください。
ページ内の単色背景の候補をまとめて探す
開発者ツールのコンソールで次のコードを実行すると、指定したタグの文字について、単色背景の候補を低い順に表示する。
(() => {
function measure(root) {
function lum(c) {
const m = /^rgba?\(\s*(\d+(?:\.\d+)?)[, ]+\s*(\d+(?:\.\d+)?)[, ]+\s*(\d+(?:\.\d+)?)(?:\s*[,/]\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(c);
if (!m) return null;
if (m[4] !== undefined) { if (Number(m[4]) !== 1) return null; }
const v = m.slice(1, 4).map(Number).map(n => {
n /= 255;
return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
});
return 0.2126 * v[0] + 0.7152 * v[1] + 0.0722 * v[2];
}
function background(el) {
let e = el, color = null;
while (e) {
const s = getComputedStyle(e);
if (Number(s.opacity) !== 1 || s.filter !== 'none' || s.mixBlendMode !== 'normal' || s.backgroundImage !== 'none') return null;
if (color === null) {
const c = s.backgroundColor;
const transparent = c === 'transparent' || /^rgba\(\s*0,\s*0,\s*0,\s*0\s*\)$/.test(c);
if (!transparent) { if (lum(c) === null) return null; color = c; }
}
e = e.parentElement;
}
return color || 'rgb(255, 255, 255)';
}
const out = [], seen = new Set();
for (const el of root.querySelectorAll('p,a,li,h1,h2,h3,span,button,time,small')) {
const cs = getComputedStyle(el);
if (!el.getClientRects().length || cs.visibility !== 'visible' || !el.textContent.trim()) continue;
const px = parseFloat(cs.fontSize) || 16, bg = background(el);
const key = cs.color + '|' + bg + '|' + px + '|' + cs.fontWeight;
const l1 = lum(cs.color), l2 = bg === null ? null : lum(bg);
const text = el.textContent.trim().slice(0, 20);
if (l1 === null || l2 === null) { out.push({text, ok:null, ratio:null, note:'手動確認:透明度・画像・未対応色など'}); continue; }
if (seen.has(key)) continue;
seen.add(key);
const r = (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
const large = px >= 24 || (px >= 14 * 96 / 72 ? parseInt(cs.fontWeight) >= 700 : false);
out.push({ratio:Math.round(r * 100) / 100, need:large ? 3 : 4.5, ok:r >= (large ? 3 : 4.5), px, w:cs.fontWeight, color:cs.color, bg, tag:el.tagName, text});
}
return out.sort((a, b) => (a.ratio === null ? Infinity : a.ratio) - (b.ratio === null ? Infinity : b.ratio));
}
console.table(measure(document).filter(x => x.ok !== true));
})();数値を計算できる候補は、文字色・背景色・文字サイズ・太さが同じ組み合わせを1件にまとめる。
手動確認になった箇所は省略しないため、件数をページ全体の合否数とは扱わない。
このコードは指定タグの要素を調べる補助です。子要素だけ色が違う文字、入力欄のプレースホルダー、iframeやShadow DOM内の文字などを網羅しません。通常表示で候補がなくても、ホバーやキーボードフォーカス時の文字を別途確認してください。
console.tableの行を console.table(measure(document)) に変えると、基準以上の候補も表示される。
表示のratioは小数第2位に丸めていますが、okの判定には丸める前の値を使っています。4.499対1は4.5対1未満なので、表示が4.5でも合格にはなりません。境界付近では表示値だけで判断せず、okと必要値needを確認してください。
このコードが見ているもの
- 非表示の要素を除外し、固定配置も候補に含める。祖先のopacity・filter・混色・背景画像がある場合は手動確認に分ける
- 背景色が透明なら、親をたどって最初に見つかった色を使う
- どこにも色が無ければ白とみなす
- 24px以上、または約18.667px以上の太字を大きい文字として扱う
背景に画像やグラデーションを使っている箇所は、この方法では正しく測れない。
その場合は、文字の背後に来る背景を1か所ずつ確かめます。文字色はCSSの指定値を基本とし、スクリーンショットの文字の縁にある、なめらかに表示するための中間色を文字色として採用しないでください。
実際に測って出た値
以下は、2026年9月20日に旧コードを運用サイトで実行した記録であり、現在の掲載コードによる再測定結果ではない。
| 文字色 | 背景色 | 大きさ | 比 | 判定 |
|---|---|---|---|---|
| 白 | ピンク(rgb(255,102,196)) | 10px | 2.64 | 4.5に届かない |
| 白 | ピンク(rgb(255,102,196)) | 16px | 2.64 | 4.5に届かない |
| rgb(51,51,51) | rgb(253,253,253) | 16px | 12.42 | 足りている |
| 白 | rgb(32,32,32) | 16px | 16.29 | 足りている |
| rgb(46,46,46) | rgb(227,227,227) | 24px | 10.58 | 足りている |
本文の色は十分な差があった一方で、ピンクの背景に白文字を置いた箇所が2.64と低く出た。
この組み合わせは、色が目立つため見えていると感じやすいが、数値では足りていない。
目立つことと読みやすいことは別なので、装飾に使う色ほど測る価値がある。
測れない値が出ることがある
実測では、比が1.00という値も出た。
旧コードでは、半透明の背景で背後の色を含めないため誤った値になる場合があった。
一方、不透明な同色どうしなら1.00が正しい値になる。
半透明は重なった色の計算が必要なので、修正版では数値の合否を出さず手動確認と表示する。
1.00や極端に低い値が出たときは、文字色と背景色、透明度、画像の有無を確認する。
比だけで原因を決めない。
足りないときの直し方
色の変更はコントラスト比そのものを変えます。一方、文字サイズや太さの変更は、適用する下限を変える方法です。同じ2色なら、文字を大きくしても比そのものは上がりません。
| やり方 | 効き方 | 見た目への影響 |
|---|---|---|
| 文字色と背景色の明暗差を広げる | 比を再計算する | 文字の印象が変わる |
| 明るい文字に対して背景色を暗くする | 比を再計算する | 配色全体に影響する |
| 文字を24px以上にする | 基準が3対1に下がる | レイアウトが変わる |
| 約18.667px以上で太字にする | 基準が3対1に下がる | 文字が太くなる |
比が3対1以上4.5対1未満なら、大きい文字の条件を満たすことで下限に届く場合があります。ただし、上の白とピンクの例は2.64対1なので、大きくするだけでは3対1にも届きません。文字色か背景色を変えて再計算します。
サイズを変えた場合は、スマートフォンでの折り返しやボタン内の収まりも確認します。背景に近い色へ薄くすると比が下がるため、見た目の印象だけで修正を終えないようにします。
測った結果を残しておく
配色は少しずつ変わるため、測った日と値を残しておくと比べられる。
- 測った日
- 足りていなかった組み合わせの数
- いちばん低かった比と、その色の組み合わせ
- 直したあとの比
記録にはURL、対象の見出しやボタン名、画面幅、ブラウザー、通常・ホバー・キーボードフォーカスなどの状態も添えます。手動確認が残った箇所を列挙し、同じ条件で修正前後を比べてください。
まとめ
- 基準は通常の文字で4.5対1、大きい文字で3対1に分かれる
- 24px以上、または約18.667px以上の太字が大きい文字にあたる
- 開発者ツールのコンソールで、指定タグの単色背景を簡易確認できる
- 実測では、ピンク背景に白文字の組み合わせが2.64と低く出た
- 比だけで原因を決めず、文字色・背景色・透明度を確認する
- サイズ変更で比自体は上がらない。3対1未満なら、大きい文字でも配色の修正が必要
下の見本で数値と手動確認の分岐を試せます。
ページ全体の表示条件を網羅する適合試験ではありません。
基準と例外はW3CのWCAG 2.2・達成基準1.4.3の解説で確認できます。ロゴや無効な操作部品などの例外があり、アイコンや枠線などの非テキスト要素は別の基準で確認します。
サイトの実装まわりはWAZAのまとめにも置いている。
GitHubのMOTOKI-LLC/WAZA-codeは過去の保管版で、この記事の掲載コードとは同期していません。
この補助コードだけでページ全体のWCAG適合を判定せず、画像・グラデーション・祖先のopacity・重なり・疑似要素・未対応の色形式・固定配置は実画面で確認してください。
測定できる例と手動確認になる例

「見本を測る」は、この節の9例だけを掲載コードと同じ関数で調べます。
比が1.00でも、不透明な白文字と白背景なら正しい計算結果です。
透明度や画像がある例は合否を出さず、手動確認へ分けます。
黒文字・白背景
白文字・白背景(読みにくい例)
半透明の文字
グラデーション背景
親の不透明度50%
18.66pxの太字
18.667pxの太字
24pxの通常文字
固定配置の文字(見本内に配置)
まだ測定していません。
コードは対象ページの開発者ツールのコンソールへ貼り付けます。
functions.phpや追加CSSへは貼り付けません。
元に戻すためのサイト設定変更はなく、コンソールの表示を消せば終了です。
実行するときは、この記事の掲載コードを使ってください。



