# 色だけで区別されるステータス表示

Source: https://easeweb.dev/learn/status-colours
Topics: 色とコントラスト > 状態、選択、グラフが、色以外でも区別できる (WCAG 1.4.1)
The fix: 各ステータスを、点の横に本文の色の言葉で書き、色は言葉を補うだけにします。または、チェック、トラック、警告のように、ステータスごとに固有の形を付け、凡例ではその横に言葉を残します。言葉はそれだけで伝わります。形でも1.4.1は満たしますが、凡例と照らし合わせる必要が残ります。
Test with: colour vision, contrast measurement, zoom, forced colors
References: https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html https://www.w3.org/WAI/WCAG22/Techniques/general/G14 https://www.w3.org/WAI/WCAG22/Techniques/general/G111 https://developer.chrome.com/docs/devtools/rendering/apply-effects#emulate_vision_deficiencies

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

## 場面

ショップのアカウントページに、注文履歴が並んでいます。注文番号、日付、合計金額、そして各行の最後に小さな色の点があります。緑は配達済み、黄は配送中、赤は支払い失敗で、一覧の上の凡例がそれを説明しています。スマートフォンでも各行が1行に収まるように、デザインは行を短く保っています。言葉なら折り返してしまうところを、点ならひと目で読めます。実装も丁寧です。各点には視覚的に隠したテキストがあり、スクリーンリーダーは行の最後で「支払い失敗」と読み上げます。

赤と緑を見分けにくい色覚特性のひとつ、2型色覚の見え方で、この一覧を見てみます。緑、黄、赤は、ほとんど同じオリーブ色になります。凡例はどの色が何を意味するかを説明していますが、凡例の3つの点も同じに見えます。注文1044は支払いに失敗していて、ショップは別のカードを待っています。しかし本人には同じように見える4件の注文が並んでいるだけで、どれに対応すればよいのか、画面のどこにも示されていません。

## 確認できる問題

WCAG 1.4.1（色の使用）は、情報を伝える視覚的な手段を色だけにしてはいけないとしています。注文のステータスも情報です。点どうしの違いは色だけで、大きさも、丸い形も、行の中の位置も同じです。凡例は助けになりません。行との対応を、同じ色で取るしかないためです。隠したテキストでも解決しません。1.4.1の解説書は、コードを通じて支援技術に伝わる情報があっても、この基準を満たすとは限らないとしています。求められているのは、色に代わる目に見える手段だからです。

1.4.1の解説書は、色で違いを示せる方法を一つだけ認めています。2つの色の明るさにも差があり、その間のコントラスト比が3:1以上なら、2つ目の視覚的な手がかりになるというものです。この3色は、この条件に遠く及びません。緑 `#2f9e44`、黄 `#b7791f`、赤 `#e03131` の間のコントラスト比は1.06:1から1.31:1しかなく、違いはほぼ色相だけです。そして色覚特性で見分けられなくなるのが、まさにその色相です。白いページに3つのステータスの点を置く限り、この例外はどんな色の組み合わせでも満たせません。言葉を添えない点には、達成基準1.4.11（非テキストのコントラスト）により白に対して3:1が必要で、その範囲には互いに3:1離れた色を2つまでしか置けず、3つは置けないためです。

## 利用者への影響

日差しの下のスマートフォンや、暗くしたノートPCの画面でも同じことが起きます。3色が互いに溶け合って見えるためです。スクリーンリーダーの利用者はここでは困りません。隠したテキストが各ステータスを伝えています。問題が起きるのは、一覧を目で見る人です。

## 自動チェックとAIの限界

マークアップに誤りはありません。各点は見えない名前が付いた空のspanで、名前を確認するスキャンは通ります。axeが色だけの区別を確認するのは文章の中のリンクだけで、一覧の点どうしを比べるルールはありません。この監査では、目に見える言葉がなく、1つの一覧や表の中で2色以上に分かれる小さな色の印を見つけられますが、その色に意味があるかどうかは人が判断する必要があるため、確認の候補として扱います。修正を頼まれたAIのコーディングツールは、点に `title` や `aria-label` を付けがちです。どちらも、誰の目にも見えないテキストが増えるだけです（titleが表示されるのは、10ピクセルの点にマウスを止めたときだけです）。色覚特性に配慮したとされる配色に替えることもあります。色相を見分けやすくなる人はいますが、色が唯一の手がかりであることは変わりません。

## 修正前：点の色だけで示し、名前はスクリーンリーダーにだけ伝えるステータス

```html
<h2>注文履歴</h2>
<ul class="legend">
  <li>
    <span class="status status-delivered"></span>
    配達済み
  </li>
  <li>
    <span class="status status-shipped"></span>
    配送中
  </li>
  <li>
    <span class="status status-failed"></span>
    支払い失敗
  </li>
</ul>
<ol class="orders">
  <li>
    <a href="/orders/1044">注文 1044</a>
    <span>10月15日</span>
    <span>$64.00</span>
    <span class="status status-failed"><span class="visually-hidden">支払い失敗</span></span>
  </li>
  …
</ol>
```

```css
.status {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}
.status-delivered {
  background: #2f9e44; /* 白の上で3.45:1 */
}
.status-shipped {
  background: #b7791f; /* 白の上で3.64:1 */
}
.status-failed {
  background: #e03131; /* 白の上で4.51:1 */
}
```

スクリーンリーダーでは各ステータスが聞こえますが、画面上の点の違いは色だけです。上の凡例も、同じ色でしか点と対応させられません。

## 修正後：点の横にステータスを書く

```html
<h2>注文履歴</h2>
<ol class="orders">
  <li>
    <a href="/orders/1044">注文 1044</a>
    <span>10月15日</span>
    <span>$64.00</span>
    <span class="status status-failed">支払い失敗</span>
  </li>
  …
</ol>
```

```css
/* 本文の色の言葉と、その前に残した点。 */
.status {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.status::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--dot);
}
.status-delivered {
  --dot: #2f9e44; /* 白の上で3.45:1 */
}
.status-shipped {
  --dot: #b7791f; /* 白の上で3.64:1 */
}
.status-failed {
  --dot: #e03131; /* 白の上で4.51:1 */
}
```

各行がステータスを言葉で示すので、色はステータスを担う役から、言葉を補う役に変わります。点は残るため、色を見分けられる人にはデザインの色分けがそのまま伝わります。一覧の上の凡例は要らなくなり、隠したテキストも外します。スクリーンリーダーは目に見える言葉を読むからです。言葉はステータスの色ではなく、本文の色で表示します。黄は白に対して3.64:1で、点には十分ですが、文字に必要な4.5:1には届きません。スマートフォンでは、言葉を消さずに、合計金額の下に折り返します。

## 修正後：ステータスごとの形を、凡例では言葉と並べる

```html
<h2>注文履歴</h2>
<ul class="legend">
  <li>
    <span class="status status-delivered"><svg aria-hidden="true"><use href="#icon-check"></use></svg></span>
    配達済み
  </li>
  <li>
    <span class="status status-shipped"><svg aria-hidden="true"><use href="#icon-truck"></use></svg></span>
    配送中
  </li>
  <li>
    <span class="status status-failed"><svg aria-hidden="true"><use href="#icon-alert"></use></svg></span>
    支払い失敗
  </li>
</ul>
<ol class="orders">
  <li>
    <a href="/orders/1044">注文 1044</a>
    <span>10月15日</span>
    <span>$64.00</span>
    <span class="status status-failed"><svg aria-hidden="true"><use href="#icon-alert"></use></svg><span class="visually-hidden">支払い失敗</span></span>
  </li>
  …
</ol>
```

```css
/* ステータスごとに固有の形を、ステータスの色で描く。 */
.status {
  display: inline-block;
  width: 18px;
  height: 18px;
}
.status svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.status-delivered {
  color: #2f9e44; /* 白の上で3.45:1 */
}
.status-shipped {
  color: #b7791f; /* 白の上で3.64:1 */
}
.status-failed {
  color: #e03131; /* 白の上で4.51:1 */
}
```

丸の中のチェック、トラック、警告の三角形が、色に頼らずにステータスを区別します。行はデザインどおりの短さのままです。WCAGの達成方法G111も、同じように色と模様を組み合わせる方法です。形も点と同じく、ページに対して3:1が必要です。線を `currentColor` で描くと、Windowsのコントラスト テーマでも形が残ります。この方法で1.4.1を満たすのは、凡例があり、その形が行の形と一致している間だけです。形はそのつど凡例で確かめる必要があり、長い一覧では時間がかかります。400%に拡大して凡例が画面の外に出ると難しく、どの記号が何を意味するかを覚えにくい人にも負担になります。

## どの方法を選ぶか

どちらも1.4.1を満たします。言葉を使ってください。凡例が要らず、どの拡大率でも、どの読み手にも伝わります。必要なのは各行にステータスの言葉が入る場所だけで、デザインファイルのスマートフォンの表示では、言葉を消さずに折り返す形で描きます。形は行の短さを保てますが、凡例に頼ります。社内のダッシュボードの密な表のように、どうしても言葉が入らない場所でだけ選び、凡例と隠したテキストには、それぞれの形の言葉を残します。

## 実装の判断

点に付けた `title` は、2つ目の手がかりになりません。表示されるのはマウスを点に止めたときだけで、タッチやキーボードでは表示されません。[ラベルやヒントがツールチップにしかない入力欄](/ja/learn/title-tooltips)でも、入力欄について同じ限界を説明しています。ステータスの色を薄くした背景に言葉を載せる柔らかいピル形も、言葉だけの場合と同じように使えます。下のデザインの案で、ほかの見せ方と合わせて紹介しています。

ステータスは、色ではなく言葉を受け取るコンポーネントにします。`<OrderStatus status="failed">` が一つの表から点と「支払い失敗」の両方を表示すれば、言葉のない点をどのページでも描けなくなります。同じ点が使われがちな在庫、支払いの状態、予約枠にも、同じ表を使えます。

Windowsのコントラスト テーマでは、ブラウザーが背景色をテーマの色に置き換えるため、修正前の点はまったく見えなくなります。1つ目の修正の言葉は残ります。2つ目の修正の形も、`currentColor` の線で描いているので残ります。塗りの色を固定したアイコンは元の色のまま描かれ、テーマの背景に紛れることがあります。この場合は[ハイコントラストモードで消えるフォーカス・アイコン・選択状態](/ja/learn/forced-colors)で扱っています。

## 修正の確認

1. Chrome DevToolsの「レンダリング」パネルで2型色覚、次に1型色覚をエミュレートし、凡例を見ずに各行のステータスが分かるか確認する。
2. OSのカラーフィルターでページをグレースケールにし、同じように確認する。
3. 各ステータスの色を隣接する背景に対して測定し、ステータスの言葉が4.5:1以上、言葉を添えないアイコンや点が3:1以上あるか確認する。
4. 400%に拡大して最後の注文までスクロールし、凡例が画面の外にある状態でステータスが読めるか確認する。
5. スマートフォンの幅で、すべての行に言葉か形が表示されているか確認する。

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ステータスの色や注文一覧のレイアウトを変更した際は、再度確認します。

## 制限

このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。色の値は例のため、実際の配色を実際の背景で測定してください。このガイドは、色の付いた印で示すステータスを扱います。ほかの場所で色だけを使う場合も同じ基準を満たさず、それぞれにガイドがあります。[色だけで区別される本文中のリンク](/ja/learn/links-in-text)、[色だけで示された必須項目](/ja/learn/required-fields)、[直し方がわからないフォームエラー](/ja/learn/accessible-form-errors)です。「赤い注文をご確認ください」のように、色で対象を指し示す指示は、[色や形、位置だけに頼る操作の指示](/ja/learn/sensory-instructions)で扱っています。塗りだけで示す選択中の項目や、色だけで区別するグラフの線も同じ問題で、今後それぞれのガイドで扱います。必要とする人と一緒に、ページ全体を確認してください。

---

このガイドをコーディングエージェントで使う: MCP https://easeweb.dev/mcp（設定は https://easeweb.dev/ja/services/developers）
