Webアクセシビリティ(a11y):開発者のための実践ガイド
アクセシビリティの基本原則、ARIA属性、キーボードナビゲーションのパターン、そしてWebアプリを誰もが使えるようにするためのテストツールを学びましょう。
世界人口の16%にあたる13億人以上が、何らかの障害を持って生活しています。Webアクセシビリティとは、スクリーンリーダー、キーボードナビゲーション、スイッチアクセス、その他の支援技術に頼るユーザーでもサイトを利用できるようにすることです。インクルージョンの観点に加え、アクセシブルなサイトは検索順位が高まり、モバイルでのパフォーマンスも向上し、法的に義務付けられているケースも少なくありません。
4つのPOUR原則
Web Content Accessibility Guidelines(WCAG)は、4つのコア原則に基づいて構築されています。コンテンツは以下の条件を満たす必要があります:
- 知覚可能(Perceivable) — 情報は、ユーザーが知覚できる形で提示されなければなりません(視覚だけに限らない)。
- 操作可能(Operable) — すべての機能がキーボードから利用できなければなりません。
- 理解可能(Understandable) — コンテンツとインターフェースは理解できるものでなければなりません。
- 堅牢(Robust) — コンテンツは支援技術が解析できるものでなければなりません。
WCAG 2.2では、3段階の適合レベルが定義されています:
- A — 最低限(必須)
- AA — ほとんどの組織が目標とする標準レベル
- AAA — 最高水準(一部コンテンツにおける理想目標)
多くの法的要件(ADA、EN 301 549、EAA)では、AA適合が求められています。
まずはセマンティックHTML
アクセシビリティに最も大きな効果をもたらすのは、目的に合った適切なHTML要素を使うことです。ブラウザとスクリーンリーダーは、セマンティック要素に対して適切な処理を既に知っています:
<!-- ❌ Div soup — セマンティクスなし -->
<div class="header">
<div class="nav">
<div class="nav-item" onclick="navigate()">Home</div>
</div>
</div>
<!-- ✅ セマンティックHTML — スクリーンリーダーが理解できる -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
主なセマンティック要素とその役割:
| 要素 | 役割 |
|---|---|
<header>、<footer> |
ランドマーク領域 |
<nav> |
ナビゲーションランドマーク |
<main> |
メインコンテンツ(1ページに1つ) |
<aside> |
補足コンテンツ |
<h1>〜<h6> |
見出し階層 |
<button> |
インタラクティブコントロール |
<a href> |
ナビゲーションリンク |
<label> |
フォームフィールドのラベル |
<table> |
表形式データ |
画像とaltテキスト
意味のある画像にはすべて、内容を説明するalt属性が必要です。装飾的な画像にはalt=""を指定し、スクリーンリーダーがスキップするようにします:
<!-- 意味のある画像 -->
<img src="chart.png" alt="2026年Q1の収益が40%増加したことを示す棒グラフ">
<!-- 装飾的な画像 -->
<img src="divider.svg" alt="">
<!-- アイコンボタン — アイコンではなくアクションを説明する -->
<button>
<img src="trash.svg" alt="アイテムを削除">
</button>
<!-- 避けるべき例:冗長な「〜の画像」という表現 -->
<!-- ❌ --> <img src="cat.jpg" alt="猫の画像">
<!-- ✅ --> <img src="cat.jpg" alt="窓辺に座っているオレンジ色のトラ猫">
カラーコントラスト
弱視や色覚障害のあるユーザーは、テキストと背景の間に十分なコントラストがあることを頼りにしています。
WCAG AAの要件:
- 通常テキスト(18pt未満):コントラスト比 4.5:1 以上
- 大きなテキスト(18pt以上または14pt太字以上):コントラスト比 3:1 以上
- UIコンポーネントおよびグラフィカルオブジェクト:3:1 以上
情報の伝達を色だけに頼ってはいけません:
<!-- ❌ 色のみによるステータス表示 -->
<span class="text-red-500">エラー</span>
<!-- ✅ 色+アイコン+テキスト -->
<span class="text-red-500 flex items-center gap-1">
<svg aria-hidden="true"><!-- エラーアイコン --></svg>
エラー:メールアドレスが無効です
</span>
フォーム:ラベル、エラー、説明文
すべてのフォームコントロールには、表示された関連ラベルが必要です:
<!-- ✅ 明示的なラベルの関連付け -->
<label for="email">メールアドレス</label>
<input id="email" type="email" aria-describedby="email-hint email-error">
<p id="email-hint" class="text-sm text-gray-500">メールアドレスを共有することはありません。</p>
<p id="email-error" role="alert" class="text-sm text-red-600" hidden>
有効なメールアドレスを入力してください。
</p>
フォームアクセシビリティの主なパターン:
for/idを使用してラベルと入力フィールドを関連付ける- ヒントテキストとエラーメッセージには
aria-describedbyを使用する - 動的エラーメッセージには
role="alert"またはaria-live="polite"を使用する aria-required="true"またはネイティブのrequired属性を使用する- 関連する入力グループは
<fieldset>と<legend>でまとめる
キーボードナビゲーション
すべてのインタラクティブ要素は、キーボードで到達・操作できなければなりません:
- Tab — フォーカス可能な要素を前方に移動
- Shift+Tab — 後方に移動
- Enter/Space — ボタン、チェックボックスを有効化
- 矢印キー — コンポーネント内のナビゲーション(メニュー、タブ、スライダー)
- Escape — モーダルを閉じる、ドロップダウンを非表示にする
フォーカスインジケーターは必ず表示されるようにしてください。代替手段なしに以下のようなことをしてはいけません:
/* ❌ フォーカスインジケーターを完全に非表示にする */
*:focus { outline: none; }
/* ✅ 視認性を維持したカスタムフォーカススタイル */
*:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
ARIA:使うべきタイミングと方法
ARIA(Accessible Rich Internet Applications)属性は、HTMLだけでは意味を伝えられない場合にセマンティクスを付加します。ARIAの第一のルール:ネイティブHTMLで対応できる場合はARIAを使わない。
<!-- 可視ラベルのない要素へのラベル付け -->
<button aria-label="ダイアログを閉じる">✕</button>
<!-- 展開状態の説明 -->
<button aria-expanded="false" aria-controls="menu">メニュー</button>
<ul id="menu" hidden>...</ul>
<!-- 動的コンテンツ用のライブリージョン -->
<div aria-live="polite" aria-atomic="true">
<!-- この領域への変更をスクリーンリーダーがアナウンスする -->
3件の結果が見つかりました
</div>
<!-- セマンティック要素が使えない場合のランドマークロール -->
<div role="search">
<input type="search" placeholder="検索...">
</div>
SPAとモーダルのフォーカス管理
シングルページアプリケーションでは、ページナビゲーションによってブラウザのフォーカスリセットが発生しません。「ページ」が読み込まれたら、意味のある場所にフォーカスを移動させましょう:
// ナビゲーション後、メイン見出しにフォーカスを移動する
document.querySelector("h1")?.focus();
モーダルの場合:
- モーダルが開いたら、モーダル内の最初のフォーカス可能な要素にフォーカスを移動する
- モーダルが開いている間は、フォーカスをモーダル内に閉じ込める(背後のコンテンツにTabが届かないようにする)
- モーダルが閉じたら、それを開いたトリガー要素にフォーカスを戻す
アクセシビリティのテスト
自動化ツール(問題の約30〜40%を検出)
- axe DevTools ブラウザ拡張機能
- Lighthouse Chrome DevToolsのアクセシビリティ監査
- WAVE ブラウザ拡張機能
手動テスト(完全なカバレッジに必須)
- キーボードのみによるナビゲーション — マウスを外して、サイト全体をナビゲートしてみる
- スクリーンリーダーのテスト — NVDA+Firefox(Windows)、VoiceOver+Safari(Mac/iOS)
- 200%ズーム — コンテンツが失われたり重なったりしないか確認する
- 色覚シミュレーション — ブラウザDevTools → レンダリング → 視覚障害のエミュレーション
読みやすさ
平易な言葉を使うことで、認知障害のあるユーザーのアクセシビリティが向上します。当サービスのReadability Scoreツールを使ってコンテンツの読解レベルを確認しましょう — 一般的な読者向けには、学年レベル8〜10を目安にしてください。
今日からできるクイックウィン
- すべての画像に
altテキストを追加する - すべてのフォーム入力に関連する
<label>要素があることを確認する - 本文テキストのカラーコントラストが4.5:1を満たしているか確認する
:focus-visibleスタイルを追加し、代替手段なしにアウトラインを削除しない- アクションには
<button>を、ナビゲーションには<a href>を使う(逆にしない) <html>要素にlang="ja"(または適切な言語コード)を追加する- 1ページに
<h1>は1つだけ使用し、論理的な見出し階層を維持する
アクセシビリティはアドオン機能ではなく、品質の特性です。最初からアクセシブルな製品を構築することは、後から修正するよりもはるかにコストが低く、すべてのユーザーにとってより良い製品を生み出します。