色とコントラストのテスト完全ガイド|WCAG対応とUI改善のチェック方法
Webサイトやアプリケーションにおける色は、ブランドイメージを伝えるためだけの装飾ではありません。文字の読みやすさ、ボタンの見つけやすさ、入力エラーの理解しやすさ、現在位置の把握しやすさなど、利用者が画面を正しく操作するための重要な情報として機能します。色の選び方に問題があると、情報が読めない、操作対象を認識できない、状態の違いが分からないといった問題が発生します。
特に、視力が低下している人、色の見え方に特性がある人、明るい屋外でスマートフォンを操作する人、品質の低いディスプレイを利用している人にとって、色とコントラストの不足は深刻な障害になります。デザイン制作時のモニターでは問題なく見えていても、利用環境が変わると急に読みにくくなる場合があるため、感覚だけで判断してはいけません。
本記事では、WCAG 2.2の達成基準をもとに、文字、背景、ボタン、フォーム、アイコン、グラフ、画像、ダークモードなどの色とコントラストを確認する方法を解説します。デザイン段階の確認方法だけでなく、CSS、JavaScript、自動テスト、手動テストを組み合わせた実践的な改善手順も紹介します。
1. 色とコントラストとは
色とコントラストのテストを正しく行うには、単に「明るい色と暗い色を組み合わせる」という理解だけでは不十分です。画面上で隣接する色の明るさにどの程度の差があるかを数値で確認し、情報の種類や文字サイズに応じて適切な基準を適用する必要があります。
また、コントラストは本文の読みやすさだけに関係するものではありません。リンク、ボタン、入力欄、選択状態、警告、グラフなど、利用者が情報を認識して操作するあらゆる場面に関係します。
1.1 コントラスト比とは
コントラスト比とは、前景色と背景色の相対的な明るさの差を示す数値です。最も差が小さい組み合わせは1対1、最も差が大きい黒と白の組み合わせは21対1になります。数値が大きいほど、一般的には前景と背景を区別しやすくなります。
ただし、コントラスト比が高ければ、すべてのデザインが自動的に優れたものになるわけではありません。極端に強い白黒の組み合わせを広い範囲に使用すると、利用者によっては眩しさや目の疲れを感じる場合があります。達成基準を満たしながら、利用場面や表示面積を考慮して調整することが重要です。
1.2 相対輝度とは
相対輝度とは、人間が感じる明るさに近づけるため、赤、緑、青の各成分を一定の計算式で変換した値です。単純にカラーコードの数値を比較するのではなく、人の目が色ごとに異なる感度を持っていることを反映して計算されます。
例えば、同じ数値差を持つ色でも、緑を多く含む色と青を多く含む色では、実際に感じる明るさが異なります。そのため、カラーコードだけを目視して「十分に離れている」と判断せず、相対輝度から算出されたコントラスト比を確認する必要があります。
1.3 前景色と背景色の関係
文字やアイコンなど、利用者が読み取る対象の色を前景色、その背後にある色を背景色として考えます。前景色だけを確認しても意味はなく、実際に組み合わせる背景色との関係でコントラスト比を計算しなければなりません。
同じグレーの文字でも、白い背景では基準を満たし、薄いグレーの背景では基準を満たさないことがあります。また、カード、モーダル、通知領域など、背景が部分的に変化する画面では、同じ文字色に複数の背景色が接する可能性も確認する必要があります。
1.4 読みやすさと見つけやすさの違い
読みやすさは、文章やラベルの内容を無理なく判読できるかという問題です。一方、見つけやすさは、画面内に存在するボタン、リンク、入力欄、通知などを利用者が素早く発見できるかという問題です。両者は関係していますが、同じ評価ではありません。
本文の文字が基準を満たしていても、主要ボタンが背景に埋もれていると、利用者は次の操作を見つけられません。反対に、ボタン自体が目立っていても、ボタン内のラベルが読みにくければ操作内容を理解できません。そのため、文字と部品の両方を個別に確認する必要があります。
1.5 色覚特性と利用環境の影響
色の見え方には個人差があり、赤と緑、青と紫などの組み合わせを区別しにくい人もいます。また、加齢、疲労、眼疾患などによっても、色や明るさの差を認識する能力は変化します。
利用環境も見え方に影響します。屋外の日光、画面の反射、省電力設定、低輝度設定、古いディスプレイ、プロジェクター表示などでは、制作環境よりもコントラストが弱く見える場合があります。実際の利用条件を想定した検証が必要です。
2. WCAGが求める色とコントラストの達成基準
WCAGでは、情報や操作を多様な利用者が認識できるようにするため、文字やUI部品に必要なコントラスト比を定めています。基準は適合レベルによって異なり、一般的なWebサイトではレベルAAを目標とするケースが多く見られます。
ただし、数値を満たすことだけが目的ではありません。色だけに依存しない情報設計、フォーカス表示、状態変化の明確化など、複数の達成基準を組み合わせて確認する必要があります。
2.1 通常文字に必要なコントラスト比
WCAGのレベルAAでは、通常サイズの文字に対して、背景とのコントラスト比を4.5対1以上にすることが求められます。本文、説明文、入力欄のラベル、ボタンラベル、パンくずリストなど、多くの文字がこの条件に該当します。
細い書体や小さな文字は、同じコントラスト比であっても実際には読みにくく見える場合があります。そのため、4.5対1を最低限の基準として扱い、重要な本文ではより高いコントラストを確保することが望まれます。
| 対象 | レベルAA | レベルAAA |
|---|---|---|
| 通常サイズの文字 | 4.5対1以上 | 7対1以上 |
| 大きな文字 | 3対1以上 | 4.5対1以上 |
2.2 大きな文字に必要なコントラスト比
大きな文字は、通常文字よりも形状を認識しやすいため、レベルAAでは3対1以上のコントラスト比が求められます。一般的な目安は、通常の太さで18ポイント以上、太字で14ポイント以上です。
CSSでは、18ポイントはおよそ24ピクセル、14ポイントはおよそ18.66ピクセルに相当します。ただし、実際の読みやすさは書体、字幅、線の細さ、表示倍率などにも左右されるため、境界値だけに依存しない確認が必要です。
| 文字の条件 | 大きな文字として扱う目安 | レベルAA |
|---|---|---|
| 通常の太さ | 約24ピクセル以上 | 3対1以上 |
| 太字 | 約18.66ピクセル以上 | 3対1以上 |
| 上記未満 | 通常文字として判定 | 4.5対1以上 |
2.3 UI部品に必要なコントラスト比
ボタンの境界線、入力欄の枠線、チェックボックス、ラジオボタン、選択状態、アイコンなど、操作や状態の認識に必要な視覚情報には、隣接色との間に3対1以上のコントラスト比が求められます。
ただし、ボタンの背景色そのものが常に周囲と3対1以上でなければならないわけではありません。部品の位置や形状が別の方法で明確に認識できる場合もあります。操作対象を識別するために必要な線や色が何かを判断し、その部分を検証することが重要です。
2.4 グラフや図形に必要なコントラスト比
グラフの線、データを示す棒、円グラフの区分、説明用の図形など、内容を理解するために必要な視覚情報にも3対1以上のコントラスト比が求められます。装飾目的の図形や、内容理解に不要な背景模様は対象外になる場合があります。
グラフでは、各色と背景のコントラストだけでなく、隣接するデータ同士を区別できるかも確認します。色だけで系列を分けるのではなく、線種、マーカー、模様、ラベルなどを併用すると、より多くの利用者が情報を理解できます。
2.5 ロゴや装飾が例外になる条件
ロゴやブランド名に含まれる文字は、文字コントラストの達成基準における例外として扱われます。また、非表示の部品、無効状態の部品、写真内に偶然含まれる文字、純粋な装飾も例外になる場合があります。
ただし、例外だからといって読みにくい状態を放置する必要はありません。ロゴが重要な導線や企業識別に使われている場合、実際の利用者が認識できることは依然として重要です。達成基準の対象外と、品質上改善しなくてよいことは区別して考えます。
3. コントラスト比を計算する方法
コントラスト比は、相対輝度の明るい側と暗い側を使用して計算します。一般的には専用ツールを利用しますが、計算の仕組みを理解しておくと、独自の検査機能やデザイントークンの検証処理を実装できます。
計算では、16進数のカラーコードを赤、緑、青の値に分解し、標準化と線形化を行ったうえで相対輝度を求めます。その後、明るい色と暗い色の輝度を式に代入します。
3.1 16進数カラーコードの変換
#1F2937のような16進数カラーコードは、赤、緑、青の3つの成分に分解します。それぞれの値を0から255の範囲で取得し、255で割ることで0から1の範囲に変換します。
3桁表記のカラーコードを使用する場合は、それぞれの文字を2回繰り返して6桁に変換します。例えば#FFFは#FFFFFF、#333は#333333として扱います。
コード例:カラーコードをRGB値へ変換する
function hexToRgb(hex) {
const normalized = hex.replace("#", "");
const fullHex =
normalized.length === 3
? normalized
.split("")
.map((character) => character + character)
.join("")
: normalized;
if (!/^[0-9a-fA-F]{6}$/.test(fullHex)) {
throw new Error("有効なカラーコードを指定してください");
}
return {
red: parseInt(fullHex.slice(0, 2), 16),
green: parseInt(fullHex.slice(2, 4), 16),
blue: parseInt(fullHex.slice(4, 6), 16),
};
}
3.2 相対輝度の算出
赤、緑、青の各成分を0から1の範囲に変換した後、一定の条件式を使って線形化します。これは、ディスプレイ上の数値と人が感じる明るさの関係が単純な比例ではないためです。
線形化した値に、赤0.2126、緑0.7152、青0.0722の係数を掛けて合計します。緑の係数が大きいのは、人間の目が緑の明るさに比較的敏感であることを反映しています。
コード例:相対輝度を求める
function toLinearChannel(value) {
const channel = value / 255;
return channel <= 0.04045
? channel / 12.92
: Math.pow((channel + 0.055) / 1.055, 2.4);
}
function getRelativeLuminance({ red, green, blue }) {
const r = toLinearChannel(red);
const g = toLinearChannel(green);
const b = toLinearChannel(blue);
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
3.3 コントラスト比の計算式
コントラスト比は、明るい側の相対輝度に0.05を加えた値を、暗い側の相対輝度に0.05を加えた値で割って求めます。計算結果は1から21までの範囲になります。
前景色と背景色の指定順に関係なく、明るい色を分子、暗い色を分母に配置します。順番を固定せずに計算すると、1未満の誤った結果が出る可能性があります。
コード例:2色のコントラスト比を計算する
function getContrastRatio(firstHex, secondHex) {
const firstLuminance = getRelativeLuminance(hexToRgb(firstHex));
const secondLuminance = getRelativeLuminance(hexToRgb(secondHex));
const lighter = Math.max(firstLuminance, secondLuminance);
const darker = Math.min(firstLuminance, secondLuminance);
return (lighter + 0.05) / (darker + 0.05);
}
const ratio = getContrastRatio("#1F2937", "#FFFFFF");
console.log(ratio.toFixed(2));
3.4 半透明色を計算する際の注意点
半透明の文字、背景、影、重なりを使用している場合、指定された色だけではコントラスト比を計算できません。半透明色が背後の色と合成された後の実際の表示色を求め、その結果を使って計算する必要があります。
例えば、黒を50%の透明度で白背景に重ねると、表示結果は純粋な黒ではなく中間のグレーになります。背景が画像やグラデーションの場合は位置によって合成結果が変わるため、最もコントラストが低くなる場所を確認します。
コード例:半透明色を背景色と合成する
function blendChannel(foreground, background, alpha) {
return Math.round(
foreground * alpha + background * (1 - alpha)
);
}
function blendRgb(foreground, background, alpha) {
return {
red: blendChannel(foreground.red, background.red, alpha),
green: blendChannel(foreground.green, background.green, alpha),
blue: blendChannel(foreground.blue, background.blue, alpha),
};
}
3.5 計算結果の丸め方
計算結果を画面に表示する際は、小数点以下2桁程度に丸めることがあります。しかし、適合判定では丸め前の数値を使用しなければなりません。実際の値が4.499である場合、表示上4.50に見えても4.5対1以上を満たしていません。
境界値に近い組み合わせは、環境差や将来のデザイン変更によって不適合になりやすいため、余裕を持たせることが重要です。通常文字では4.5対1ぎりぎりではなく、5対1以上を内部基準にする方法も有効です。
4. 文字色と背景色をテストする方法
文字のコントラストテストでは、本文だけでなく、見出し、注釈、リンク、ボタンラベル、入力補助、エラーメッセージなど、画面に表示されるすべての意味のある文字を確認します。
共通の文字色を一度確認するだけでは不十分です。同じ文字色でも、配置される背景、状態、透明度、画像との重なりによって結果が変化します。
4.1 本文テキストの確認
本文は長時間読まれる可能性があるため、最低基準を満たすだけでなく、疲れにくさも考慮します。白背景に極端に薄いグレーを使用すると、洗練された印象に見えても、文章量が増えるほど読みにくさが目立ちます。
本文色は、通常状態だけでなく、引用、注釈、カード内文章、モーダル内文章、固定フッター内文章など、背景が異なる場所ごとに確認します。デザインシステム内で本文色の利用可能な背景を制限すると、誤用を減らせます。
4.2 見出しテキストの確認
見出しは本文より大きく表示されることが多いため、条件を満たせば3対1以上で適合する場合があります。ただし、見出しが必ず大きな文字に分類されるとは限りません。文字サイズと太さを実際のCSS指定で確認します。
大きな見出しでも、ブランドカラー、背景画像、グラデーションとの組み合わせによって読みづらくなることがあります。特に画像上の見出しは、画面幅や画像の切り抜き位置が変わると背景色も変わるため、複数の表示幅で検証します。
4.3 補助テキストの確認
日付、注釈、文字数表示、入力例などの補助テキストは、重要度が低いことを表現するために薄い色が選ばれがちです。しかし、情報の重要度が低いことと、読めなくてもよいことは同じではありません。
補助テキストでも、利用者が内容を理解するために必要であれば4.5対1以上を確保します。視覚的な優先順位は、文字サイズ、余白、配置、太さなどを組み合わせて表現し、コントラストだけを大幅に下げないようにします。
4.4 リンク文字の確認
本文中のリンクを色だけで区別する場合、リンク色と周囲の本文色の間にも十分な違いが必要です。また、リンク色と背景色のコントラストも通常文字の基準を満たす必要があります。
より確実な方法は、下線を使用してリンクであることを示すことです。通常時に下線を省略する場合でも、マウスを重ねた状態やキーボードフォーカス時に明確な変化を付けます。
| 確認対象 | 必要な判定 |
|---|---|
| リンク文字と背景 | 通常文字として4.5対1以上 |
| リンク文字と本文文字 | 色だけで識別させる場合は十分な差を確保 |
| フォーカス状態 | 枠線や下線など色以外の変化を表示 |
| 訪問済みリンク | 背景との文字コントラストを維持 |
4.5 プレースホルダー文字の確認
入力欄のプレースホルダーは薄いグレーで表示されることが多く、コントラスト不足が起きやすい要素です。入力例や形式を伝える重要な情報として使用する場合は、通常文字と同様に読み取れる必要があります。
プレースホルダーを入力欄のラベル代わりに使用してはいけません。入力を開始すると消えてしまうため、利用者が何を入力する欄か確認できなくなります。常に表示されるラベルを別に設け、プレースホルダーは補足情報として使用します。
コード例:読みやすいプレースホルダーを指定する
.form-input {
color: #1f2937;
background-color: #ffffff;
border: 1px solid #6b7280;
}
.form-input::placeholder {
color: #5f6672;
opacity: 1;
}
5. 通常文字と大きな文字の違い
通常文字と大きな文字では、WCAGが求める最低コントラスト比が異なります。そのため、文字サイズや太さを正確に確認せず、見た目の印象だけで判定すると誤りが生じます。
また、文字サイズが基準を超えていても、極端に細い書体や装飾的な書体では読みづらい場合があります。数値上の分類と実際の可読性を分けて評価することが重要です。
5.1 文字サイズによる違い
通常の太さの文字は、18ポイント以上で大きな文字として扱われます。CSSピクセルに換算すると、およそ24ピクセルです。24ピクセル未満の文字は、原則として通常文字の基準で確認します。
ブラウザの拡大表示によって画面上の文字が大きく見えていても、判定では指定された文字サイズを基準に考えます。利用者側の拡大を前提として、制作側のコントラスト不足を正当化することはできません。
| CSS上の文字サイズ | 通常の太さでの分類 | レベルAAの目安 |
|---|---|---|
| 16ピクセル | 通常文字 | 4.5対1以上 |
| 20ピクセル | 通常文字 | 4.5対1以上 |
| 24ピクセル | 大きな文字 | 3対1以上 |
| 32ピクセル | 大きな文字 | 3対1以上 |
5.2 文字の太さによる違い
太字の場合は14ポイント以上が大きな文字として扱われ、CSSではおよそ18.66ピクセル以上が目安になります。ただし、CSSのfont-weight: 700を指定しただけで、すべての書体が同じ太さに表示されるわけではありません。
使用する書体に該当する太字データがない場合、ブラウザが擬似的な太字を生成することがあります。その結果、想定より線が細く見える可能性があります。実際に配信される書体と表示状態で確認する必要があります。
| 文字の太さ | 文字サイズ | 分類 |
|---|---|---|
| 標準 | 約18.66ピクセル | 通常文字 |
| 太字 | 約18.66ピクセル | 大きな文字 |
| 標準 | 24ピクセル | 大きな文字 |
| 太字 | 24ピクセル | 大きな文字 |
5.3 見出しと本文の違い
見出しは文字サイズが大きく、太字で表示されることが多いため、3対1以上で条件を満たす場合があります。一方、本文は16ピクセル前後で表示されることが多く、4.5対1以上が必要です。
同じブランドカラーを見出しと本文の両方に使用すると、見出しでは適合しても本文では不適合になることがあります。文字用途ごとに使用可能な色を定義し、本文用と大文字用の色を分ける方法が有効です。
| 使用場所 | 代表的なサイズ | 必要なコントラスト比 |
|---|---|---|
| ページタイトル | 32ピクセル・太字 | 3対1以上 |
| セクション見出し | 24ピクセル・太字 | 3対1以上 |
| 小見出し | 18ピクセル・太字 | 条件により4.5対1以上 |
| 本文 | 16ピクセル・標準 | 4.5対1以上 |
5.4 日本語と欧文の見え方の違い
日本語の漢字や仮名は、欧文のアルファベットよりも一文字あたりの線や形が複雑です。同じ文字サイズでも、細い書体や低いコントラストでは、細部が潰れたり輪郭が曖昧になったりすることがあります。
特に小さな注釈や表内の文字では、数値基準を満たしていても読みにくい場合があります。日本語を中心とするサイトでは、最低基準より高いコントラストを確保し、行間や文字間も含めて確認することが望まれます。
| 比較項目 | 日本語 | 欧文 |
|---|---|---|
| 文字形状 | 線が多く複雑になりやすい | 比較的単純な形が多い |
| 小サイズ表示 | 細部が潰れやすい | 書体により判読しやすい |
| 必要な確認 | 漢字を含む長文で検証 | 大文字・小文字の両方で検証 |
| 改善方法 | 太さ、行間、コントラストを確保 | 字幅、太さ、文字間を確認 |
5.5 細い書体と太い書体の違い
細い書体は、背景との境界を構成する画素が少ないため、同じ色を使用しても太い書体より弱く見える場合があります。高解像度のモニターではきれいに見えても、低解像度や明るい環境では線が消えやすくなります。
太い書体に変更すれば必ず解決するわけではありません。過度に太い文字は、小さなサイズで内部の空間が潰れ、別の読みにくさを生む場合があります。色、サイズ、太さ、書体をまとめて調整します。
| 比較項目 | 細い書体 | 太い書体 |
|---|---|---|
| 低コントラスト時 | 線が消えやすい | 輪郭を認識しやすい |
| 小さい文字 | 判読性が低下しやすい | 内部が潰れる場合がある |
| 適した用途 | 大きな見出し、短い装飾文字 | 本文、ラベル、操作要素 |
| 確認方法 | 実機と低輝度環境で確認 | 文字の潰れと間隔を確認 |
6. ボタンとUI部品のコントラストテスト
ボタンやUI部品では、ラベルの読みやすさだけでなく、部品そのものの存在、境界、状態を認識できるかを確認します。文字の達成基準だけを検査しても、操作可能な場所が分からなければアクセシビリティは確保できません。
通常、マウスを重ねた状態、キーボードフォーカス状態、押下状態、選択状態、無効状態など、複数の状態が存在します。各状態を個別に検証します。
6.1 塗りつぶしボタンの確認
背景色で塗りつぶされたボタンでは、ボタン内の文字とボタン背景のコントラスト比を確認します。文字が通常サイズの場合は4.5対1以上、大きな文字の場合は3対1以上が必要です。
周囲の背景とボタン背景の差も確認します。輪郭がなくても形状や配置からボタンと判断できる場合はありますが、背景色が周囲とほぼ同じで操作対象を発見できない場合は改善が必要です。
コード例:主要ボタンの色を変数で管理する
:root {
--button-primary-background: #174ea6;
--button-primary-text: #ffffff;
--button-primary-hover: #123f87;
--button-primary-focus: #ffbf47;
}
.primary-button {
color: var(--button-primary-text);
background-color: var(--button-primary-background);
border: 2px solid transparent;
padding: 0.75rem 1.25rem;
font-weight: 700;
}
.primary-button:hover {
background-color: var(--button-primary-hover);
}
6.2 枠線ボタンの確認
枠線だけで表現するボタンは、背景との境界が弱くなりやすい部品です。枠線がボタンの存在を示す重要な情報である場合、その枠線と隣接する背景の間に3対1以上のコントラストを確保します。
文字色と枠線色を同じにすると設計しやすくなりますが、背景との文字コントラストと部品コントラストの両方を満たす必要があります。マウスを重ねた際に背景を塗りつぶす場合は、その状態の文字色も再確認します。
6.3 アイコンボタンの確認
検索、閉じる、共有、削除などをアイコンだけで表現するボタンでは、アイコンと背景の間に3対1以上のコントラストを確保します。細い線のアイコンは実際の表示で弱く見えるため、線の太さも重要です。
アイコンの意味が一般的でない場合は、視覚的に見えていても操作内容を理解できません。利用可能な名前を設定し、必要に応じてツールチップや文字ラベルを併用します。
コード例:アイコンボタンに利用可能な名前を付ける
<button class="icon-button" type="button" aria-label="検索を開く">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path
d="M10.5 4a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13Zm0-2a8.5 8.5 0 1 1 5.2 15.2l4.55 4.55-1.42 1.42-4.55-4.55A8.5 8.5 0 0 1 10.5 2Z"
/>
</svg>
</button>
6.4 選択状態の確認
タブ、メニュー、フィルター、ページ番号などの選択状態を色だけで示すと、色の違いを認識しにくい利用者が現在位置を判断できない場合があります。下線、太字、枠線、チェックマークなどを併用します。
選択前と選択後の色がそれぞれ背景に対して十分なコントラストを持っていても、両状態の違いが小さければ状態変化を認識できません。単独の色だけでなく、状態間の視覚的な差を確認します。
6.5 無効状態の確認
無効状態のUI部品は、一部のコントラスト達成基準から例外として扱われる場合があります。しかし、利用者が部品の存在や無効である理由を理解できないと、操作に混乱が生じます。
単にボタンを極端に薄くするのではなく、無効状態を示す表示、補足文、利用可能になる条件などを伝える方法が有効です。特に重要な操作では、無効化するより、操作後に不足情報を説明する設計が適している場合もあります。
7. フォーカスと操作状態の色を確認する方法
キーボードやスイッチ装置を利用する人にとって、フォーカス表示は現在どの要素を操作しているかを把握するための重要な手掛かりです。ブラウザ標準の輪郭線を無効にし、代替表示を用意しない実装は避けなければなりません。
フォーカス、マウスを重ねた状態、押下、選択、展開など、操作によって変化する状態は、それぞれ明確に区別できる必要があります。
7.1 キーボードフォーカスの確認
Tabキーでページ内を移動し、すべての操作要素に明確なフォーカス表示が出るか確認します。フォーカス輪郭は、部品の背景とページ背景の両方に接する可能性があるため、隣接する色との関係を確認します。
輪郭線が細すぎる、要素から離れすぎる、角の一部しか表示されないといった問題にも注意します。固定ヘッダーやスクロール領域によって、フォーカス要素が隠れないことも確認します。
コード例:見やすいフォーカス表示を設定する
:focus-visible {
outline: 3px solid #ffbf47;
outline-offset: 3px;
}
.button:focus-visible {
box-shadow:
0 0 0 2px #ffffff,
0 0 0 5px #174ea6;
}
7.2 マウスを重ねた状態の確認
マウスを重ねた状態では、利用者に操作可能であることを伝えるため、色、下線、背景、影などを変化させます。ただし、通常状態からの変化が小さすぎると、反応していることが分かりません。
色を変更する場合は、変更後の文字やアイコンが背景とのコントラスト基準を満たすか確認します。背景色を暗くした結果、文字とのコントラストが不足することもあるため、状態ごとに計算します。
7.3 押下状態の確認
ボタンを押している間の状態は、操作が受け付けられていることを伝えます。背景色を暗くする、位置をわずかに移動する、影を減らすなど、複数の変化を組み合わせると認識しやすくなります。
押下時に文字色と背景色の関係が変わる場合は、短時間の表示であっても読み取れるようにします。押下状態を極端に暗くした結果、アイコンやラベルが見えなくならないよう注意します。
7.4 選択状態と未選択状態の確認
チェックボックス、ラジオボタン、切り替えスイッチでは、選択部分の色だけで状態を示さないようにします。チェックマーク、内部の点、スイッチの位置など、形状による違いを残します。
選択色と背景色のコントラストに加えて、チェックマークと選択色のコントラストも確認します。外枠、内部記号、背景という複数の隣接関係を個別に評価します。
7.5 展開状態と折りたたみ状態の確認
アコーディオンやメニューでは、開いているか閉じているかを色だけで示すと状態を理解しにくくなります。矢印の向き、プラスとマイナスの変化、状態を示す文字などを併用します。
展開時に背景色を変更する場合、見出し文字やアイコンのコントラストを再確認します。さらに、展開された内容との境界が弱くならないよう、余白や枠線も含めて設計します。
8. ダークモードのコントラストテスト
ダークモードでは、背景を暗くして文字を明るくするため、単純に色を反転すればよいと考えられがちです。しかし、明るい文字が暗い背景上で膨張して見える現象や、鮮やかな色が強く見えすぎる問題があります。
ライトモードで適合している配色をそのまま反転しても、ダークモードで快適に読めるとは限りません。各モードを独立した配色として検証します。
8.1 ダーク背景と本文文字の確認
純粋な黒背景に純粋な白文字を使用すると、最大のコントラストを確保できますが、広い範囲では眩しく感じる利用者もいます。濃いグレーの背景と、わずかに明度を抑えた白系文字を組み合わせる方法があります。
ただし、眩しさを避けるために文字を暗くしすぎると、通常文字に必要な4.5対1を下回ります。本文、補助文、無効状態を段階的に設計し、それぞれ実際の背景との比率を確認します。
8.2 ブランドカラーの見え方
ライトモード用の濃いブランドカラーは、暗い背景上ではほとんど見えない場合があります。反対に、明るく調整したブランドカラーは、広いボタン背景として使用すると刺激が強くなることがあります。
ダークモードでは、同じ色相を保ちながら明度や彩度を調整した専用色を用意します。ロゴ、リンク、ボタン、通知など、用途ごとに必要なコントラストを確認します。
8.3 影と境界線の確認
暗い背景では、黒い影がほとんど見えないため、カードやモーダルの階層を表現しにくくなります。境界線、背景の明度差、内側のハイライトなどを使って領域を区別します。
カード背景とページ背景が近すぎると、操作領域や情報のまとまりを認識できません。境界線が識別に必要な場合は、隣接する背景との間に十分な差を設けます。
8.4 画像とイラストの確認
ライトモード用に作られた透過画像は、暗い背景上で輪郭が消える場合があります。黒い線で描かれたロゴやイラスト、暗い影を含む画像は特に注意が必要です。
必要に応じて、ダークモード用の画像、明るい輪郭線、背景付きの表示を用意します。画像内の文字や重要な図形が背景に埋もれないことも確認します。
8.5 OS設定との連動
利用者のOS設定に合わせてダークモードを切り替える場合は、prefers-color-schemeを使用できます。ただし、OS設定への自動追従だけでなく、サイト内で表示を変更できる選択肢を提供すると利便性が高まります。
手動で選択した設定を保存する場合は、初期表示時のちらつきにも注意します。CSS変数を使用して各色を用途別に管理すると、モード間の不整合を減らせます。
コード例:配色モードをCSS変数で切り替える
:root {
--page-background: #ffffff;
--surface-background: #f5f7fa;
--text-primary: #1f2937;
--text-secondary: #4b5563;
--border-color: #6b7280;
--link-color: #174ea6;
}
@media (prefers-color-scheme: dark) {
:root {
--page-background: #121417;
--surface-background: #1d2127;
--text-primary: #f3f4f6;
--text-secondary: #c8cdd5;
--border-color: #8b949e;
--link-color: #8ab4f8;
}
}
9. ブランドカラーをWCAG対応させる方法
ブランドカラーは企業やサービスの印象を形成する重要な要素ですが、すべての用途に同じ色を使用できるとは限りません。ロゴでは問題なくても、本文、ボタン、リンク、背景ではコントラスト不足になる可能性があります。
ブランドの一貫性を保つには、単一の色だけを固定するのではなく、用途別の明度段階や組み合わせ規則を定義することが重要です。
9.1 ブランドカラーを用途別に分ける
基準となるブランドカラーに加えて、文字用、背景用、境界線用、マウスを重ねた状態用などの色を用意します。それぞれを同じ色相の明度違いとして設計すると、ブランドらしさを保ちやすくなります。
例えば、ロゴには基準色、白背景上のリンクには濃い色、濃い背景上の文字には明るい色を使用します。色名ではなく用途名で管理すると、実装時の誤用を防げます。
9.2 明度を調整する
背景とのコントラストが不足している場合、前景色を暗くする、または明るくすることで改善できます。白背景上の文字では暗くし、暗い背景上の文字では明るくするのが一般的です。
ただし、単純に黒や白を混ぜると、ブランドカラーの印象が大きく変わることがあります。色相と彩度の変化も確認し、ブランド担当者とアクセシビリティ担当者が共通の許容範囲を定めます。
9.3 彩度を調整する
彩度を高くしても、必ずコントラスト比が上がるわけではありません。コントラスト比は主に相対輝度の差で決まるため、鮮やかさだけを増やしても基準を満たさない場合があります。
鮮やかな赤や青は、暗い背景上で強く見える一方、細い文字では輪郭が不安定に見えることがあります。彩度と明度を別々に調整し、実際の文字やUI部品で確認します。
9.4 ブランドカラーの組み合わせを制限する
ブランドカラーが複数ある場合、すべての色同士を自由に組み合わせると、不適合な配色が大量に発生します。使用可能な前景色と背景色の組み合わせをあらかじめ定義します。
例えば、黄色背景には黒系文字のみ、濃い青背景には白系文字のみというように規則を設定します。デザインツールと実装の両方で同じ規則を共有すると、確認作業を減らせます。
9.5 ブランドガイドラインへ反映する
アクセシビリティ対応色を一時的な修正として扱うと、新しいページや広告で同じ問題が繰り返されます。ブランドガイドラインに、用途、背景、文字サイズ、利用可能な組み合わせを記載します。
色見本だけでなく、「本文には使用不可」「大きな見出しのみ使用可能」「白文字との組み合わせに限定」といった条件を示すことが重要です。デザイナー以外の担当者でも判断できる内容にします。
コード例:用途名でブランドカラーを管理する
:root {
--brand-base: #3973d6;
--brand-text-on-light: #174b9b;
--brand-background-strong: #174ea6;
--brand-text-on-strong: #ffffff;
--brand-background-soft: #e8f0fe;
--brand-border: #345f9f;
}
10. 画像・グラデーション・動画上の文字をテストする方法
写真や動画の上に文字を重ねるデザインでは、背景色が一定ではありません。ある位置では読めても、別の位置では文字と似た明るさになり、コントラストが不足することがあります。
レスポンシブ表示では画像の切り抜き位置が変わるため、デスクトップだけでなくスマートフォンやタブレットでも確認します。
10.1 写真上の文字を確認する
写真上の文字は、文字が重なる範囲の中で最もコントラストが低い部分を基準に評価します。人物、空、建物、影などが混在する画像では、部分ごとの明るさが大きく変わります。
文字の位置を固定していても、画像が差し替えられる運用では安全性を維持できません。画像選定ルール、文字背景、暗幕処理などを組み合わせます。
10.2 暗幕を重ねる
画像全体または文字周辺に半透明の暗幕を重ねると、白文字とのコントラストを安定させやすくなります。ただし、暗幕の透明度が低すぎると、明るい画像部分で基準を満たさない可能性があります。
画像ごとに透明度を調整すると運用負荷が高くなるため、一定の条件で基準を満たせる設計を選びます。重要な文字には不透明な背景を使用する方法もあります。
コード例:画像に暗幕を重ねる
.hero {
position: relative;
color: #ffffff;
background-image: url("/images/hero.jpg");
background-position: center;
background-size: cover;
}
.hero::before {
position: absolute;
inset: 0;
content: "";
background: rgba(0, 0, 0, 0.62);
}
.hero__content {
position: relative;
z-index: 1;
}
10.3 グラデーション上の文字を確認する
グラデーションでは位置によって背景色が変化するため、開始色と終了色だけを確認しても不十分です。文字が重なる領域全体を確認し、途中の色でコントラストが低下しないか評価します。
複数色のグラデーションや透明度を含むグラデーションでは、計算がさらに複雑になります。文字の背後に単色の面を設けると、安定したコントラストを確保しやすくなります。
10.4 動画上の文字を確認する
動画背景は時間によって明るさや色が変化するため、静止画よりもコントラストの保証が難しくなります。ある場面では読めても、次の場面で文字が背景に消える可能性があります。
動画全体に一定の暗幕を重ねる、文字部分に不透明な背景を付ける、動画とは別の領域に文字を配置するなどの対策が有効です。再生停止時や読み込み前の代替画像でも確認します。
10.5 文字の影と縁取りを使用する
文字の影や縁取りは、複雑な背景上で輪郭を補強するために使われます。ただし、細い影だけでは十分なコントラストを確保できない場合があります。
縁取りを使用する場合は、文字本体、縁取り、背景の関係を確認します。装飾的な影に依存するより、背景面や暗幕を使用した方が安定した結果を得やすくなります。
11. フォームの色とコントラストを改善する方法
フォームでは、ラベル、入力欄、境界線、入力内容、補助文、エラー、成功状態など、多数の色が使用されます。どれか一つが見えにくいだけでも、入力や送信を完了できなくなる可能性があります。
特にエラー表示を赤だけで表現する設計は避けます。アイコン、文章、枠線、関連付けを組み合わせ、色を認識できなくても内容が伝わるようにします。
11.1 入力欄の境界線を確認する
入力欄の枠線が背景とほとんど同じ色の場合、入力可能な領域を見つけられません。枠線が入力欄の形状を示す主要な情報であれば、背景との間に3対1以上のコントラストを確保します。
背景色の違いで入力欄を示す場合は、その差が十分に認識できるか確認します。枠線、背景、余白を組み合わせると、より安定した識別が可能になります。
11.2 ラベルと入力内容を確認する
入力欄のラベルと入力済み文字は、通常文字として背景との間に4.5対1以上を確保します。ラベルを小さく薄い文字で表示すると、入力内容を理解しにくくなります。
必須項目を色だけで示さず、「必須」という文字や記号を使用します。記号を使う場合は、その意味をフォームの冒頭などで説明します。
11.3 エラー表示を確認する
エラーを赤い枠線だけで示すと、色の違いを認識しにくい利用者が問題に気付けない場合があります。エラーアイコン、具体的な説明文、入力欄との関連付けを追加します。
赤いエラーメッセージは、白背景とのコントラストが不足しやすい色の一つです。鮮やかな赤をそのまま使用せず、十分に濃い赤を選びます。
コード例:エラー内容を入力欄に関連付ける
<label for="email">メールアドレス</label>
<input
id="email"
name="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" class="form-error">
有効なメールアドレスを入力してください。
</p>
.form-error {
color: #a61b1b;
font-weight: 700;
}
input[aria-invalid="true"] {
border: 3px solid #a61b1b;
}
11.4 成功状態を確認する
入力成功や送信完了を緑色だけで伝えると、状態を認識できない利用者がいます。チェックマーク、完了メッセージ、見出しなどを併用します。
成功メッセージの背景を薄い緑、文字を濃い緑にする場合は、文字と背景のコントラストを確認します。アイコンが意味を伝える場合は、アイコンと背景の関係も確認します。
11.5 フォーカス状態を確認する
入力欄にフォーカスした際は、通常状態より明確な枠線や輪郭を表示します。単に枠線の色を薄いグレーから薄い青へ変えるだけでは、変化が分かりにくい場合があります。
線の太さ、外側の輪郭、背景色などを組み合わせます。エラー状態とフォーカス状態が同時に発生する場合、どちらの情報も失われない設計にします。
12. CSSで色とコントラストを管理する方法
色を個別のCSS宣言として大量に記述すると、変更漏れや不適合な組み合わせが発生しやすくなります。用途別の変数を使用し、許可された組み合わせを共通化することが重要です。
実装時には、通常状態だけでなく、マウスを重ねた状態、フォーカス、押下、選択、エラー、ダークモードまで一貫して管理します。
12.1 CSS変数を使用する
CSS変数を使うと、色の値を一か所で管理できます。単純な色名ではなく、本文、補助文、背景、境界線、エラーなどの用途名を付けます。
--gray-700のような色階調だけを直接使用すると、利用場所に適した色か判断しにくくなります。用途変数から色階調変数を参照する二段階の管理も有効です。
コード例:用途別の色変数を定義する
:root {
--color-neutral-900: #1f2937;
--color-neutral-700: #4b5563;
--color-neutral-500: #6b7280;
--color-neutral-100: #f3f4f6;
--color-white: #ffffff;
--text-primary: var(--color-neutral-900);
--text-secondary: var(--color-neutral-700);
--page-background: var(--color-white);
--surface-background: var(--color-neutral-100);
--control-border: var(--color-neutral-500);
}
12.2 文字用途を限定する
ブランドカラーや状態色を本文に直接使用すると、背景によって不適合になる可能性があります。本文用、リンク用、反転文字用など、利用できる用途を限定します。
CSSクラスの命名でも、色名ではなく意味を表現します。例えば.text-blueではなく.text-linkや.text-informationとすると、将来色を変更しても名称と意味が一致します。
12.3 状態色を一括管理する
通常、マウスを重ねた状態、フォーカス、押下、無効状態の色を部品ごとに個別管理すると、不整合が生じやすくなります。共通の状態変数を用意し、部品間で一貫性を持たせます。
ただし、同じ状態色をすべての背景で使用できるとは限りません。明るい背景用と暗い背景用に分け、使用可能な組み合わせを定義します。
12.4 強制カラーモードへ対応する
一部の利用者は、OSやブラウザの機能によって独自の高コントラスト配色を使用します。この環境では、指定した背景色や影が無効になり、部品の境界が消える場合があります。
forced-colorsを使用し、境界線やフォーカス表示がシステム色で維持されるか確認します。色だけに依存していない設計であれば、強制カラーモードでも情報が残りやすくなります。
コード例:強制カラーモードで境界を維持する
@media (forced-colors: active) {
.button {
border: 2px solid ButtonText;
}
.button:focus-visible {
outline: 3px solid Highlight;
}
.selected-item {
border: 2px solid Highlight;
}
}
12.5 ユーザー指定色を尊重する
利用者がブラウザや支援機能で色を変更している場合、固定色を多用した設計は設定を妨げることがあります。システム色や継承を適切に利用し、必要以上に色を固定しないようにします。
背景画像に依存した情報や、CSS背景だけで示すアイコンは、ユーザー指定色の環境で消える可能性があります。HTMLの文字や境界線など、別の手段でも情報が残るようにします。
13. 自動テストでコントラスト違反を検出する方法
自動テストを導入すると、ページ数が多いサイトでも一定の条件を継続的に確認できます。新しい機能や配色変更による問題を早期に検出できる点が大きな利点です。
一方、自動テストだけですべての問題を検出することはできません。画像上の文字、状態変化、色だけに依存した情報などは、手動確認が必要になる場合があります。
13.1 ブラウザ開発者ツールを使用する
主要なブラウザの開発者ツールには、文字色と背景色のコントラスト比を表示する機能があります。対象要素を選択し、色の指定を確認することで、基準を満たしているか判断できます。
ただし、複雑な背景、透明度、画像、擬似要素などでは、正しい背景色を取得できない場合があります。表示された結果を無条件に信用せず、実際の重なりを確認します。
13.2 axe-coreを使用する
axe-coreは、Webページのアクセシビリティ上の問題を検出するための検査エンジンです。文字コントラストを含む複数の規則を自動的に確認できます。
開発中のブラウザ検査、単体テスト、結合テスト、継続的な検査など、さまざまな工程に組み込めます。検出結果には対象要素と理由が含まれるため、修正箇所を特定しやすくなります。
コード例:axe-coreをページ内で実行する
import axe from "axe-core";
async function runAccessibilityCheck() {
const results = await axe.run(document, {
runOnly: {
type: "tag",
values: ["wcag2aa", "wcag22aa"],
},
});
if (results.violations.length > 0) {
console.error("アクセシビリティ違反を検出しました");
console.table(
results.violations.map((violation) => ({
id: violation.id,
impact: violation.impact,
description: violation.description,
}))
);
}
}
runAccessibilityCheck();
13.3 Playwrightと組み合わせる
Playwrightを使用すると、実際のブラウザでページを開き、axe-coreによる検査を自動化できます。主要ページや共通部品を対象にすることで、変更による問題を継続的に検出できます。
ログイン後の画面、モーダルを開いた状態、エラー表示後など、操作によって現れる状態もテスト対象にできます。初期表示だけでなく、重要な利用手順に沿って検査します。
コード例:Playwrightでアクセシビリティ検査を行う
import { test, expect } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";
test("トップページに重大な違反がない", async ({ page }) => {
await page.goto("http://localhost:3000");
const results = await new AxeBuilder({ page })
.withTags(["wcag2aa", "wcag22aa"])
.analyze();
expect(results.violations).toEqual([]);
});
13.4 デザインシステムを検査する
完成したページだけでなく、ボタン、入力欄、タブ、通知などの共通部品を一覧表示したページを検査します。各状態を同時に表示すると、通常、フォーカス、エラー、無効状態の確認が容易になります。
部品単位で問題を修正すれば、その部品を使用する複数ページへ改善を反映できます。ページごとの修正よりも効率的で、将来の再発も防ぎやすくなります。
13.5 継続的な検査へ組み込む
アクセシビリティ検査を継続的インテグレーションへ組み込み、変更のたびに実行します。重大なコントラスト違反が追加された場合に処理を失敗させることで、不適合な変更が公開される可能性を減らせます。
ただし、既存の違反が多いプロジェクトで一度にすべてを失敗扱いにすると、運用が停止する場合があります。新規違反のみを禁止し、既存違反を段階的に減らす方法もあります。
14. 手動テストで確認すべき項目
自動検査は効率的ですが、人間が画面を見て操作しなければ判断できない問題があります。特に、色だけに依存した情報、動的な状態、画像上の文字、グラフの識別は手動確認が欠かせません。
手動テストでは、通常の制作環境だけでなく、拡大表示、低輝度、明るい環境、スマートフォンなど、異なる条件を再現します。
14.1 ページ全体を目視する
最初にページ全体を見て、薄すぎる文字、背景に埋もれるボタン、境界が不明瞭なカードなどを確認します。数値検査を始める前に、視覚的な問題が集中している場所を把握できます。
目視だけで適合判定をしてはいけませんが、数値上は適合していても読みにくい箇所を発見できます。細い書体、小さな注釈、複雑な背景などを重点的に確認します。
14.2 キーボードだけで操作する
マウスを使用せず、Tabキー、ShiftとTabキー、Enterキー、Spaceキー、矢印キーなどで操作します。フォーカス位置が常に見えるか、操作順序が理解できるかを確認します。
フォーカス輪郭が背景と重なって消える場所や、モーダルの背後へ移動してしまう問題にも注意します。画面をスクロールした際に、フォーカス要素が固定領域の裏へ隠れないことも確認します。
14.3 グレースケールで確認する
画面をグレースケールにすると、色相の違いを取り除き、明るさの差や形状だけで情報を理解できるか確認しやすくなります。赤と緑で区別した状態や、複数色のグラフの問題を発見できます。
ただし、グレースケールで区別できることだけで、すべての色覚特性に対応できるわけではありません。あくまで補助的な確認方法として使用し、専用の表示シミュレーションや実利用者の評価と組み合わせます。
14.4 拡大表示で確認する
ブラウザを200%以上に拡大し、文字やUI部品の表示を確認します。文字が大きくなるだけでなく、レイアウトが変化し、背景や部品の重なりが発生する可能性があります。
デスクトップ幅のまま拡大した場合と、狭い画面幅で表示した場合の両方を確認します。レスポンシブ表示によって画像の位置や背景色が変わる箇所は、コントラストも再評価します。
14.5 実機と異なる明るさで確認する
スマートフォン、タブレット、ノートパソコンなど、複数の実機で確認します。画面の輝度を下げた状態や、明るい場所での表示も試します。
制作モニターでわずかに見える境界線は、別の画面では消える場合があります。最低基準ぎりぎりの配色ほど環境差の影響を受けやすいため、余裕のある色設計が重要です。
15. コントラスト改善を運用へ定着させる方法
一度すべてのページを修正しても、運用ルールがなければ、新しいページ、キャンペーン、機能追加によって同じ問題が再発します。色とコントラストを制作工程に組み込み、継続的に管理する必要があります。
担当者個人の注意力に依存せず、デザインシステム、確認項目、自動検査、レビュー手順を組み合わせることが重要です。
15.1 色の利用規則を文書化する
本文、補助文、リンク、背景、境界線、エラー、成功状態など、用途ごとに使用できる色を文書化します。カラーコードだけでなく、使用可能な背景と必要な文字サイズも記載します。
禁止例も示すと判断しやすくなります。例えば、「この青は白背景上の大きな見出しにのみ使用可能」「このグレーは無効状態以外に使用しない」といった具体的な条件を設定します。
15.2 デザインレビューに組み込む
デザインレビュー時に、主要画面の文字、ボタン、フォーム、状態変化を確認します。開発後に問題を発見すると、色だけでなく部品構造やブランド規則まで変更が必要になる場合があります。
デザインツール上で色の組み合わせを確認し、使用可能なスタイルを共通部品として登録します。自由な色指定を減らすことで、制作段階の不適合を防ぎます。
15.3 開発レビューに組み込む
実装レビューでは、CSS変数の使用、状態別の色、フォーカス表示、ダークモード、強制カラーモードを確認します。デザイン通りに実装されていても、ブラウザの既定動作や透明度によって結果が変わることがあります。
コードレビュー用の確認項目にアクセシビリティを追加し、変更された部品の状態を一覧で確認できる環境を用意します。スクリーンショットだけでなく、実際に操作して確認します。
15.4 問題の優先順位を決める
すべての問題を同時に修正できない場合は、利用者への影響と利用頻度をもとに優先順位を決めます。ログイン、購入、申込、問い合わせなど、主要な手順に含まれる問題を優先します。
本文が読めない、主要ボタンを認識できない、エラー内容が分からないといった問題は、操作完了を妨げる可能性が高いため、早急な対応が必要です。装飾的な要素は後の段階で改善できます。
15.5 改善状況を数値で追跡する
コントラスト違反数、違反があるページ数、共通部品の適合率、自動検査の通過率などを記録します。問題数だけでなく、新規違反の発生件数や修正までの日数も確認します。
数値は品質改善の方向を確認するために使用し、単に違反件数を減らすことだけを目的にしないようにします。重要な利用手順が実際に使いやすくなったか、利用者テストや問い合わせ内容も合わせて評価します。
おわりに
色とコントラストのテストでは、本文文字のコントラスト比だけを確認して終わることはできません。ボタン、フォーム、アイコン、フォーカス表示、状態変化、画像、グラフ、ダークモードなど、情報の理解や操作に必要なすべての視覚要素を確認する必要があります。
WCAGの数値基準は重要な判断材料ですが、基準ぎりぎりの配色がすべての環境で快適に見えるとは限りません。日本語の複雑な文字形状、細い書体、画面の明るさ、屋外利用なども考慮し、最低値より余裕のある設計を目指すことが大切です。
デザイン段階の確認、CSS変数による管理、自動検査、キーボード操作を含む手動テストを継続的に行えば、コントラスト不足の再発を減らせます。色を装飾としてだけでなく、利用者へ情報を届ける機能として扱うことが、WCAG対応と使いやすいUIの両方につながります。
EN
JP
KR