# 現在のページを見た目だけで示すパンくずリスト

Source: https://easeweb.dev/learn/breadcrumbs
Topics: メニューとナビゲーション > パンくずリストで現在地がわかる (WCAG 1.3.1)
The fix: パンくずリストを固有の名前を付けたnavに番号付きリストとして入れ、どのパンくずが現在のページかをコードで示します。最後のパンくずを残してaria-current="page"を付け、その属性から見た目を設定するか、パンくずリストを一つ上の階層で終え、ページ名は見出しに任せます。
Test with: screen reader, keyboard, forced colors
References: https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html https://www.w3.org/WAI/WCAG22/Techniques/html/H97 https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/ https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-current https://design-system.service.gov.uk/components/breadcrumbs/ https://www.aaron-gustafson.com/notebook/identifying-accessibility-data-gaps-in-codegen-models/

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

## 場面

ショップのマグカップのカテゴリーページは、Home / Kitchen / Mugsというパンくずリストで始まります。見慣れた、すっきりしたデザインです。HomeとKitchenは下線付きの青いリンクで、今いるページのMugsは下線のない灰色です。目で見る人は、検索エンジンから来ても、KitchenのなかのMugsにいること、クリック一つで上の階層へ戻れることがすぐに分かります。

スクリーンリーダーの利用者がTabキーで同じページを移動すると、「Home、リンク」「Kitchen、リンク」「Mugs、リンク」と聞こえます。Mugsが今いるページであることも、三つのリンクがパンくずリストであることも伝わりません。1行ずつ読むと、パンくずの間のスラッシュも読まれることがあります。パンくずリストはナビゲーションとして読み上げられず、スクリーンリーダーのランドマーク一覧にも出ないので、そこへ移動することもできません。ヘッダーのリンクに続く、ただの三つのリンクです。

## 確認できる問題

パンくずリストは関係を示しています。そのリンクはサイト内を移動するためのまとまりで、トップページからこのページまで順に並び、最後の一つが表示中のページです。WCAG 1.3.1「情報及び関係性」は、見た目で示した情報をコードかテキストでも伝えることを求めています。この例では、まとまりはレイアウトにしかありません。パンくずリストは `div` で、支援技術に対しては何もまとめないからです。達成方法H97は、関連するリンクを `nav` に入れることで1.3.1を満たします。順序も一行の文字の並びにしかなく、パンくずがいくつあるかを伝えるリストがありません。現在のページも見た目にしかありません。`current` クラスはMugsを灰色にするだけで、ブラウザーにとって意味がないためです。

## 利用者への影響

パンくずリストは、ショップのカテゴリーや商品ページ、ヘルプセンター、ドキュメントのサイトなど、ほぼどのサイトにもあります。たいていは一つの共通コンポーネントから作られるため、一か所直せばすべてのページに届きます。特に重要なのは、検索エンジンや共有されたリンクから来たページです。パンくずリストが、どこに着いたかを知るいちばんの近道になります。階層の深い大きなサイトでも同じです。

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

自動チェックは、名前のあるリンクが三つあるとして合格にします。`current` や `active` といったクラス名には意味がないので、一つのリンクが現在地として装飾されていることは分かりません。`div` に並んだリンクがパンくずリストであることも分かりません。EaseWebの診断では、クラスや名前からパンくずリストと分かる場所で、表示中のページへのリンクが隣のパンくずと違う見た目なのに、`aria-current` も現在のページだと伝えるテキストもないものを報告します。ナビゲーションのランドマークの外にあるパンくずリストは、そのリンクを添えて、人が確認する項目として渡します。AIによるコード生成もこの穴を確実には埋めません。Aaron Gustafsonが2025年に公開したGPT-4の検証では、`nav` に名前がなく、`aria-current="page"` もないパンくずリストが生成されました。二つのページでパンくずリストを聞いて確かめてください。

## 修正前：クラスで最後を示した、並べただけのリンク

```html
<div class="breadcrumbs">
  <a href="/">Home</a>
  <span class="sep">/</span>
  <a href="/kitchen">Kitchen</a>
  <span class="sep">/</span>
  <a href="/kitchen/mugs" class="current">Mugs</a>
</div>
<h1>Mugs</h1>
```

```css
.breadcrumbs {
  display: flex;
  gap: 0.5rem;
}
.breadcrumbs .sep {
  color: #5b6670;
}
.breadcrumbs .current {
  color: #5b6670;
  text-decoration: none;
}
```

`current` クラスはMugsの見た目を変えるだけで、`div` も何もまとめません。スクリーンリーダーは「Home、リンク」「Kitchen、リンク」「Mugs、リンク」と読み、句読点の読み上げ設定によっては間のスラッシュも読みます。

## 修正後：名前付きのnav、リスト、aria-current

```html
<nav class="breadcrumbs" aria-label="Breadcrumb">
  <ol>
    <li>
      <a href="/">Home</a>
    </li>
    <li>
      <a href="/kitchen">Kitchen</a>
    </li>
    <li>
      <a href="/kitchen/mugs" aria-current="page">Mugs</a>
    </li>
  </ol>
</nav>
<h1>Mugs</h1>
```

```css
.breadcrumbs ol {
  display: flex;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
}
.breadcrumbs li + li::before {
  content: "";
  display: inline-block;
  height: 0.8em;
  margin-right: 0.5rem;
  border-right: 1px solid #5b6670;
  transform: rotate(15deg);
}
.breadcrumbs [aria-current="page"] {
  color: #5b6670;
  text-decoration: none;
}
```

デザインは変わりません。どのパンくずも描かれたとおりに見えます。パンくずリストは固有の名前を持つ `nav` になったため、スクリーンリーダーは入るときに「Breadcrumb、ナビゲーション」と読み、ランドマーク一覧にも並びます。番号付きリストにもなり、「リスト、3項目」として上から順に読まれます。Mugsに付けた `aria-current="page"` により、スクリーンリーダーはそこで「現在のページ」と読みます。灰色もこの属性で選ぶため、見た目とコードが別のパンくずを示すことはありません。区切りは境界線で描いた細い斜線なので、スクリーンリーダーが読むテキストはありません。

## 修正後：一つ上の階層で終わるパンくずリスト

```html
<nav class="breadcrumbs" aria-label="Breadcrumb">
  <ol>
    <li>
      <a href="/">Home</a>
    </li>
    <li>
      <a href="/kitchen">Kitchen</a>
    </li>
  </ol>
</nav>
<h1>Mugs</h1>
```

```css
.breadcrumbs ol {
  display: flex;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
}
.breadcrumbs li + li::before {
  content: "";
  display: inline-block;
  height: 0.8em;
  margin-right: 0.5rem;
  border-right: 1px solid #5b6670;
  transform: rotate(15deg);
}
```

普段の見た目が変わります。パンくずリストはKitchenで終わり、そのすぐ下の見出しがページ名を示します。パンくずリストの中に現在のページとして描くものがないので、コードで伝える関係も、見た目とコードが食い違うものもありません。スクリーンリーダーは「Breadcrumb、ナビゲーション」「リスト、2項目」「Home、リンク」「Kitchen、リンク」と読み、続いて見出しの「Mugs」を読みます。GOV.UK Design Systemのパンくずリストもこの形で、現在のページの一つ上のセクションで終わります。パンくずリストは名前付きの `nav` とリストのままで、それが支援技術に対してパンくずリストであることを示します。

## どの方法を選ぶか

どちらも1.3.1を満たします。デザインに最後のパンくずがあるとき、またはパンくずリストの下の見出しが離れていたり、パンくずと言葉が違ったりするときは、最後のパンくずを残して `aria-current="page"` を付けてください。デザインは描かれたとおりのまま、見た目は属性から決まります。見出しがすぐ下にあり、同じ言葉を示すときは、一つ上の階層で終えてください。どのパンくずもどこかへ行くリンクになり、合わせておく状態もありません。

## 実装の判断

修正の周りにも、判断が必要な点があります。

- テキストの最後のパンくず：ARIA Authoring Practicesの例では、ここと同じく最後のパンくずを `aria-current="page"` を付けたリンクにしています。`aria-current="page"` を付けたテキストのパンくずでも1.3.1を満たし、ページを再読み込みするだけのリンクを減らせます。
- 属性の代わりの隠したテキスト：テーマやCMSでパンくずの文字は変えられても属性は付けられない場合は、「（現在のページ）」のような視覚的に隠したテキストを中に加えます。メニューについては[現在のページを見た目だけで示すナビゲーション](/ja/learn/current-page)で説明しています。
- 区切り：テキストを使わず、境界線や背景画像としてCSSで描くか、マークアップに入れて `aria-hidden="true"` で隠します。`content` に `"/"` や `"›"` などのテキストを書くと、ほとんどのブラウザーでスクリーンリーダーに読まれます。
- 名前：スクリーンリーダーが「ナビゲーション」を補うので、「Breadcrumb」で足ります。[区別できない複数のナビゲーションランドマーク](/ja/learn/landmark-names)を参照してください。
- リスト：SafariのVoiceOverは、CSSでマーカーを消したリストをリストとして読まないことがありますが、ここのように `nav` の中にあるリストはリストのまま読みます。`nav` の外に置くパンくずリストでは、`ol` に `role="list"` を加えます。
- シングルページアプリ：画面遷移でページを読み込まずに入れ替えるときは、パンくずリストも作り直し、`aria-current` も一緒に移します。[読み上げられないSPAの画面遷移](/ja/learn/route-changes)を参照してください。

Windowsのコントラスト テーマでも現在のパンくずが見分けられるようにします。強制配色ではどのリンクも同じ色になるため、灰色だけで区別したパンくずはほかと同じに見えます。下線がない、あるいは太字にしたパンくずなら、区別が残ります。

## 修正の確認

1. コードかブラウザーの検証ツールで、パンくずリストが固有の名前の `nav` と番号付きリストになっていること、最後のパンくずに `aria-current="page"` か隠したテキストがあるか、パンくずリストが一つ上の階層で終わっていること、現在のページの見た目が同じ条件から設定されていること、区切りにテキストがないことを確認する。
2. スクリーンリーダーのランドマーク一覧を開き、パンくずリストがサイトのメインメニューとは別の名前で並ぶか確認する。
3. スクリーンリーダーでパンくずリストを読み、現在のページが現在のページと読まれること（または一つ上の階層で終わり、ページの見出しが続くこと）と、区切りが読まれないことを確認する。
4. サイトの深い階層へ移り、パンくずリストで上へ戻って、見た目と読み上げの両方が新しいページへ移ったか確認する。
5. Windowsのコントラスト テーマをオンにし、現在のパンくずがその前のリンクと見分けられるか確認する。

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のパンくずリストのコンポーネントを変更した際は、再度確認します。

## 制限

このサンプルは、どのサイトでも同じ結果になることを保証するものではありません。`aria-current` やランドマークの読み上げ方はスクリーンリーダーによって異なり、句読点の読み方は設定で変わります。利用者が使うスクリーンリーダーで確かめてください。パンくずリストが役に立つのは、サイトの実際の構造に沿っているときだけです。来た経路で変わったり、階層を飛ばしたりするパンくずリストは、ないのと同じくらい迷わせます。長い一覧の最後にあるページのリンクには、別の問題があります。[現在のページも行き先も伝えないページネーション](/ja/learn/pagination)を参照してください。サイトのメインメニューも、同じ属性で現在のページを示します。[現在のページを見た目だけで示すナビゲーション](/ja/learn/current-page)を参照してください。

---

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