---
title: "カード型コンポーネントのアクセシブルな実装パターン"
date: 2026-02-19
categories: column
author: 二俣
canonical: https://www.liberogic.jp/topics/20260220-accessible-card-patterns/
---

# カード型コンポーネントのアクセシブルな実装パターン

![](https://images.microcms-assets.io/assets/4b13731f29254025b91c8d846198ffc9/8cc0b3d1941f4c71af1c59b4155a5528/20260220_accessible-card-patterns.png)

記事一覧などでよく使うカード型コンポーネント。見た目はシンプルですが、アクセシビリティを考慮すると意外に奥深い設計課題があります。典型的なカードとして上から 画像、記事タイトル、記事の概要、詳細リンクと縦に並ぶレイアウトでの実装パターンを考えてみましょう。

記事一覧などでよく使うカード型コンポーネント。見た目はシンプルですが、アクセシビリティを考慮すると意外に奥深い設計課題があります。

典型的なカードとして上から

- 画像
- 記事タイトル
- 記事の概要
- 詳細リンク

と、縦に並ぶレイアウトでの実装パターンを考えてみましょう。

## 設計時の主な検討ポイント

### 1. 視覚順序とHTML構造

スクリーンリーダーは基本的にHTMLの記述順序で読み上げます。WCAG 2.0の**達成基準1.3.2（意味のある順序、レベルA）**では、**視覚的な順序とHTML順序を一致させることが基本原則**としています。

ただし、CSSで順序を変更すること自体がWCAG違反になるわけではありません。視覚的な順序とHTML順序が異なっても、コンテンツが理解可能であれば問題ありません。状況に応じて柔軟に判断することが重要です。

### 2. 画像の扱い方

記事カードの画像は、多くの場合**装飾的**です。記事タイトルがあれば内容は十分伝わるため、画像の説明を読み上げる必要性は低いと言えます。

装飾的画像として扱う場合`alt=""`だけで十分です。

```
`<img src="thumbnail.jpg" alt="">
`
```

### 3. 詳細リンクのラベル

「詳細を見る」のような汎用的なテキストは、以下の理由で避けるべきです。

**視覚的な問題**

周辺のコンテキストなしでは、何のリンクか判断できない

**スクリーンリーダーの問題**

リンクリスト機能で一覧表示した際、すべて「詳細を見る」となり区別できない

**音声認識の問題**

複数の同じテキストがあると、番号での選択が必要になり操作が煩雑

理想的には「〇〇の詳細を見る」のように、リンク単体で目的が分かるテキストにすべきですが、ここでは「詳細を見る」というデザインをそのまま再現する場合の実装方法を扱います。

### 4. カードのクリッカブル領域

UX向上のため、カード全体をクリック可能にしたいケースがよくあります。実装方法は複数ありますが、それぞれアクセシビリティへの影響が異なります。

### 5. カードはarticleにするかdivにするか

どちらにするかは、コンテンツの性質によります。

`<article>`が適している場合:

- カードの内容が独立したコンテンツとして成立する

`<div>`で問題ない場合:

- 単なるリンクのグループとして機能する
- カード自体に意味的な独立性がない

一般的なブログ記事一覧や商品一覧のカードでは、`<article>` が適切です。 ただし、複数の`<article>`を使用する場合は、スクリーンリーダーのランドマーク移動を考慮し、`aria-labelledby`または`aria-label`で各記事を識別できるようにすることが推奨されます（WCAG 2.4.6、レベルAA）。

`aria-labelledby` を使用する場合は、IDはユニークな値になるように注意してください。

## 視覚順序とHTML構造について

### **パターン1: 視覚的順序とHTML順序を一致させる**

```
`<article class="article-card" aria-labelledby="article-title">
  <img src="thumbnail.jpg" alt="">
  <h3 id="article-title"><a href="#" class="card-link">記事タイトル</a></h3>
  <p>記事の概要...</p>
  <a href="#" class="card-detail-link">
	  <span class="visually-hidden">記事タイトル:</span>詳細を見る
  </a>
</article>
`
```

HTMLの記述順序が視覚順序と完全に一致するため、シンプルで直感的です。

※ `<article>`の最初の要素は見出しが望ましいとされますが、絶対的な要件ではありません。 視覚順序との一致を優先する場合、このパターンで問題ありません。

補足:

音声認識ソフト（Dragon、Voice Controlなど）は画面に表示されているテキストを基準に動作します。 `visually-hidden (sr-only)`を使用することで視覚テキストが保持され、音声認識での操作が可能になります。 ほか、リンクラベルの対応でOKなパターンとNGなパターンの実装例です。

```
`<!-- 以下は可視テキストがアクセシブルな名前に含まれているのでOK -->
<a href="#" id="link-text" class="card-detail-link" aria-labelledby="link-text article-title">
  詳細を見る
</a>
<a href="#" aria-label="詳細を見る：記事タイトル">
  詳細を見る
</a>
<!-- 以下は可視テキストがアクセシブルな名前に含まれていないのでNG -->
<a href="#" class="card-detail-link" aria-labelledby="article-title">
  詳細を見る
</a>
<a href="#" class="card-detail-link" aria-label="記事タイトル">
  詳細を見る
</a>
`
```

### **パターン2: CSS orderで視覚順序を調整**

```
`<article class="article-card" aria-labelledby="article-title">
  <h3 id="article-title"><a href="#">記事タイトル</a></h3>
  <p>記事の概要...</p>
  <a href="#" class="card-detail-link">
	  <span class="visually-hidden">記事タイトル:</span>詳細を見る
  </a>
  <img src="thumbnail.jpg" alt="">
</article>
`
```

```
`.article-card {
  display: flex;
  flex-direction: column;
}

.article-card img {
  order: -1;
}
`
```

`<article>`の最初の要素が見出しになるため、セマンティック的により望ましい構造です。

装飾的画像（`alt=""`）の場合、読み上げ順序への影響はありません（画像はスキップされるため）。

注意:

- 画像が意味を持ち、alt属性を指定している場合、視覚順序と読み上げ順序が変わるためこの構造は適さない
- キーボードのTab順序はHTMLの順序に従うため、カード内に複数のフォーカス可能な要素がある場合は、フォーカス順が論理的な流れを壊していないことを確認してください。

## カードのクリッカブル領域を全体にしたい場合

### **パターン3: 擬似要素でカード全体をクリッカブルに**

この方法では、タイトルのリンクの擬似要素でカード全体をカバーし、「詳細を見る」は視覚的な装飾として`<span>`にします。

「詳細を見る」を`<a>`のまま`tabindex="-1"`や`aria-hidden="true"` にしても、スクリーンリーダーのリンクリストや、要素移動モードでノイズになるので、`<span>`にするのがいいと考えます。

```
`<article class="article-card" aria-labelledby="article-title">
  <img src="thumbnail.jpg" alt="">
  <h3 id="article-title"><a href="#" class="card-link">記事タイトル</a></h3>
  <p>記事の概要...</p>
  <span class="card-detail-link">詳細を見る</span>
</article>
`
```

```
`.article-card {
  position: relative;
}

.card-link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

.card-link:focus-visible {
  outline: none;
}

.card-link:focus-visible::after {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* カード内に複数のリンクがある場合の例 */
.article-card a:not(.card-link) {
  position: relative;
  z-index: 2;
}
`
```

**メリット:**

- セマンティックな構造を保てる
- スクリーンリーダーで自然に読み上げられる
- カード内に複数のリンクを配置できる（カテゴリ、タグ、著者リンクなど）

**デメリット:**

- `z-index`の管理が必要（ただし、一度設定すれば問題ない）

### **パターン4: カード全体を**`<a>`で囲む

この方法では、カード全体が一つのリンクになるため、「詳細を見る」は自然に`<span>`になります。

```
`<article class="article-card" aria-labelledby="article-title">
  <a href="#" class="card-link">
    <img src="thumbnail.jpg" alt="">
    <h3 id="article-title">記事タイトル</h3>
    <p>記事の概要...</p>
    <span class="card-detail-link">詳細を見る</span>
  </a>
</article>
`
```

**メリット:**

- 実装がシンプル
- CSSの調整が容易

**デメリット:**

- スクリーンリーダーによっては全テキストが連結して読み上げられる場合がある （特にVoiceOverでは「記事タイトル記事の概要...詳細を見る、リンク」となる）
- カード内に複数のリンクを配置できない

### **各パターンのサンプル**

## まとめ

アクセシブルなカード型コンポーネントの実装には、複数のアプローチが存在します。重要なのは、「これが唯一の正解」という実装パターンは存在せず、**状況によって最適な解が変わる**ということです。

実装にあたっては以下を意識しておくことが重要です。

1. 実際に使う人が困らない実装を選ぶ
2. 画像の意味、カードの用途、サイト全体の構成を考慮する
3. 実用的で保守しやすい実装を優先する
