| name | accessibility |
| description | Web アクセシビリティの設計・実装ガイド(フレームワーク非依存)。WCAG 2.1 準拠の基本原則、セマンティック HTML、ARIA パターン、キーボードナビゲーション、フォームアクセシビリティ、カラーコントラスト、動的コンテンツ、テスト観点をカバー。WCAG 準拠、a11y 対応が必要な時に使用。 |
Web アクセシビリティガイド
WCAG 2.1 準拠を目標としたフレームワーク非依存のアクセシビリティ設計・実装ガイド。
WCAG 2.1 の 4 原則
| 原則 | 意味 | 主な要件 |
|---|
| 知覚可能 (Perceivable) | 情報を知覚できる | テキスト代替、キャプション、コントラスト |
| 操作可能 (Operable) | UI を操作できる | キーボード操作、十分な時間、発作防止 |
| 理解可能 (Understandable) | 情報と操作が理解できる | 読みやすさ、予測可能、入力支援 |
| 堅牢 (Robust) | 支援技術と互換性がある | 適切なマークアップ、名前と役割 |
準拠レベル
Level A: 最低限の要件(必須)
Level AA: 推奨レベル(一般的な目標)
Level AAA: 最高レベル(全ページ準拠は非現実的)
→ 通常は Level AA 準拠を目標にする
セマンティック HTML
ランドマーク
<header> → バナー(サイトヘッダー)
<nav> → ナビゲーション
<main> → メインコンテンツ(ページに1つ)
<aside> → 補足コンテンツ
<footer> → フッター
<section> → セクション(見出し付き)
<article> → 独立したコンテンツ
見出し階層
- h1 はページに 1 つ
- 階層を飛ばさない(h1 → h3 は NG)
- 見出しだけで文書構造が理解できるように
- 装飾目的で見出しタグを使わない
インタラクティブ要素
原則: ネイティブ HTML 要素を優先する
✅ <button> → クリック可能な操作
✅ <a href=""> → ナビゲーション
✅ <input>, <select>, <textarea> → フォーム入力
❌ <div onclick=""> → ボタンの代替(キーボード操作不可)
❌ <span> でリンク模倣 → スクリーンリーダーが認識しない
ARIA パターン
ARIA の基本原則
1. ネイティブ HTML で解決できるなら ARIA は不要
2. ネイティブのセマンティクスを上書きしない
3. インタラクティブな要素はキーボード操作可能にする
4. focusable な要素に role="presentation" を使わない
5. すべてのインタラクティブ要素にアクセシブルな名前を付ける
よく使う ARIA 属性
| 属性 | 用途 | 例 |
|---|
| aria-label | 要素に名前を付ける | <button aria-label="メニューを閉じる">×</button> |
| aria-labelledby | 別要素で名前を定義 | <div aria-labelledby="title-id"> |
| aria-describedby | 説明を関連付け | <input aria-describedby="help-text"> |
| aria-expanded | 展開状態 | <button aria-expanded="false"> |
| aria-hidden | 支援技術から隠す | <span aria-hidden="true">装飾</span> |
| aria-live | 動的更新の通知 | <div aria-live="polite"> |
| aria-required | 必須フィールド | <input aria-required="true"> |
| aria-invalid | エラー状態 | <input aria-invalid="true"> |
| role | 要素の役割を定義 | <div role="alert"> |
詳細: references/aria-patterns.md
キーボードナビゲーション
必須のキーボード操作
| キー | 動作 |
|---|
| Tab | 次のフォーカス可能な要素へ |
| Shift + Tab | 前のフォーカス可能な要素へ |
| Enter / Space | ボタン/リンクの実行 |
| Escape | モーダル/ポップアップを閉じる |
| 矢印キー | ラジオボタン、タブ、メニュー内の移動 |
フォーカス管理
原則:
- フォーカスインジケーターを常に表示する(outline: none 禁止)
- フォーカス順序が論理的であること(tabindex の乱用を避ける)
- tabindex="0": 自然な順序でフォーカス可能にする
- tabindex="-1": プログラムでフォーカスするが Tab では到達しない
- tabindex > 0: 使用禁止(順序が混乱する)
フォーカストラップ:
- モーダル表示時はモーダル内にフォーカスを閉じ込める
- モーダルを閉じたら元の要素にフォーカスを戻す
スキップリンク
ページ先頭に「メインコンテンツへスキップ」リンクを配置
→ キーボードユーザーがナビゲーションを飛ばせる
→ 通常は非表示、フォーカス時に表示
フォームアクセシビリティ
ラベル
必須:
- すべての入力フィールドに関連付けられたラベルを付ける
- <label for="id"> または aria-label / aria-labelledby
placeholder はラベルの代替にならない:
❌ <input placeholder="メールアドレス">
✅ <label for="email">メールアドレス</label>
<input id="email" placeholder="example@mail.com">
エラー表示
原則:
- エラーメッセージをフィールドに関連付ける(aria-describedby)
- エラー発生時にフォーカスをエラー箇所に移動
- 色だけでエラーを示さない(アイコン + テキストも使う)
- aria-invalid="true" でエラー状態を伝える
- エラーサマリーをフォーム上部に表示(複数エラー時)
バリデーション
- リアルタイムバリデーションは aria-live で結果を通知
- 必須フィールドは aria-required="true" + 視覚的な印
- 入力形式のヒントを aria-describedby で提供
カラーコントラスト
WCAG AA 基準:
- 通常テキスト: コントラスト比 4.5:1 以上
- 大きなテキスト(18px 以上 or 14px bold): 3:1 以上
- UI コンポーネント・アイコン: 3:1 以上
原則:
- 色だけで情報を伝えない(形、テキスト、パターンも使う)
- リンクは色だけでなく下線でも区別
- グラフは色以外のパターンも使用
- ダークモード時もコントラスト比を確認
動的コンテンツ
ライブリージョン
aria-live の使い分け:
- "polite": ユーザーの操作を中断しない(推奨)
→ トースト通知、検索結果の更新
- "assertive": 即座に通知(緊急時のみ)
→ エラーメッセージ、セッション期限切れ
aria-atomic:
- "true": 領域全体を読み上げ
- "false": 変更部分のみ読み上げ(デフォルト)
SPA のページ遷移
- ページ遷移時にページタイトルを更新
- 新しいコンテンツにフォーカスを移動(または通知)
- ローディング状態を aria-busy="true" で伝える
- 読み込み完了を通知(aria-live 領域で)
アクセシビリティテスト
自動テスト
最低限のチェック:
- HTML バリデーション
- ランドマーク構造
- alt テキストの存在
- ラベルの関連付け
- コントラスト比
- ARIA 属性の正しい使用
手動テスト
キーボードテスト:
1. Tab キーですべての操作可能な要素に到達できるか
2. フォーカスインジケーターが見えるか
3. Enter/Space でボタン/リンクが動作するか
4. Escape でモーダルが閉じるか
スクリーンリーダーテスト:
1. 見出し構造でナビゲーションできるか
2. フォームのラベルが読み上げられるか
3. エラーメッセージが通知されるか
4. 動的コンテンツの更新が伝わるか
詳細: references/wcag-checklist.md
レビューチェックリスト
リファレンス