アクセシビリティ(WCAG 2.2) は何をしますか?
このスキルは、スクリーンリーダー、スイッチコントロール、キーボードナビゲーションを使用するユーザーを含むすべてのユーザーに対して、デジタルインターフェースを知覚可能、操作可能、理解可能、かつ堅牢(POUR)にします。WCAG 2.2達成基準の技術的実装に焦点を当てています。
使用するタイミング
- Web、iOS、Android向けのUIコンポーネント仕様を定義する場合。
- 既存のコードにアクセシビリティの障壁や準拠のギャップがないか監査する場合。
- ターゲットサイズ(最小)やフォーカス表示などの新しいWCAG 2.2基準を実装する場合。
- 高レベルのデザイン要件を技術的属性(ARIAロール、トレイト、ヒント)にマッピングする場合。
中核概念
- POUR原則: WCAGの基礎(知覚可能、操作可能、理解可能、堅牢)。
- セマンティックマッピング: 汎用コンテナではなくネイティブ要素を使用して、組み込みのアクセシビリティを提供する。
- アクセシビリティツリー: 支援技術が実際に「読み取る」UIの表現。
- フォーカス管理: キーボード/スクリーンリーダーカーソルの順序と可視性を制御する。
- ラベリングとヒント:
aria-label、accessibilityLabel、contentDescriptionを通じてコンテキストを提供する。
仕組み
ステップ1: コンポーネントのロールを特定する
機能的な目的を判断します(例: これはボタンか、リンクか、タブか?)。カスタムロールに頼る前に、最もセマンティックなネイティブ要素を使用します。
ステップ2: 知覚可能属性を定義する
- テキストのコントラストが4.5:1(標準)または3:1(大テキスト/UI)であることを確認します。
- テキスト以外のコンテンツ(画像、アイコン)にテキスト代替を追加します。
- レスポンシブリフロー(400%ズームまで機能を失わずに表示)を実装します。
ステップ3: 操作可能なコントロールを実装する
- 最小24x24 CSSピクセルのターゲットサイズを確保します(WCAG 2.2 SC 2.5.8)。
- すべてのインタラクティブ要素がキーボードで到達可能であり、可視のフォーカスインジケータがあることを確認します(SC 2.4.11)。
- ドラッグ操作に代わる単一ポインタ操作を提供します。
ステップ4: 理解可能なロジックを確保する
- 一貫したナビゲーションパターンを使用します。
- 説明的なエラーメッセージと修正の提案を提供します(SC 3.3.3)。
- 「冗長な入力」を避けるために、同じデータを二度要求しないようにします(SC 3.3.7)。
ステップ5: 堅牢な互換性を検証する
- 正しい
Name, Role, Valueパターンを使用します。 - 動的なステータス更新には
aria-liveまたはライブリージョンを実装します。
アクセシビリティアーキテクチャ図
flowchart TD
UI["UI コンポーネント"] --> Platform{プラットフォーム?}
Platform -->|Web| ARIA["WAI-ARIA + HTML5"]
Platform -->|iOS| SwiftUI["アクセシビリティトレイト + ラベル"]
Platform -->|Android| Compose["セマンティクス + ContentDesc"]
ARIA --> AT["支援技術(スクリーンリーダー、スイッチ)"]
SwiftUI --> AT
Compose --> AT
クロスプラットフォームマッピング
| 機能 | Web (HTML/ARIA) | iOS (SwiftUI) | Android (Compose) |
|---|---|---|---|
| プライマリラベル | aria-label / <label> | .accessibilityLabel() | contentDescription |
| セカンダリヒント | aria-describedby | .accessibilityHint() | Modifier.semantics { stateDescription = ... } |
| アクションロール | role="button" | .accessibilityAddTraits(.isButton) | Modifier.semantics { role = Role.Button } |
| ライブ更新 | aria-live="polite" | .accessibilityLiveRegion(.polite) | Modifier.semantics { liveRegion = LiveRegionMode.Polite } |
例
Web: アクセシブルな検索
<form role="search">
<label for="search-input" class="sr-only">商品を検索</label>
<input type="search" id="search-input" placeholder="検索..." />
<button type="submit" aria-label="検索を実行">
<svg aria-hidden="true">...</svg>
</button>
</form>
iOS: アクセシブルなアクションボタン
Button(action: deleteItem) {
Image(systemName: "trash")
}
.accessibilityLabel("アイテムを削除")
.accessibilityHint("このアイテムをリストから完全に削除します")
.accessibilityAddTraits(.isButton)
Android: アクセシブルなトグル
Switch(
checked = isEnabled,
onCheckedChange = { onToggle() },
modifier = Modifier.semantics {
contentDescription = "通知を有効にする"
}
)
避けるべきアンチパターン
- Divボタン: ロールとキーボードサポートを追加せずに、クリックイベントのために
<div>や<span>を使用する。 - 色のみの意味: 色の変更だけでエラーやステータスを示す(例: 境界線を赤くするだけ)。
- フォーカスを閉じ込めないモーダル: フォーカスをトラップしないモーダル。キーボードユーザーがモーダルを開いている間に背景コンテンツを操作できてしまう。フォーカスはモーダル内に閉じ込められ、かつ
Escapeキーまたは明示的な閉じるボタンで脱出できる必要があります(WCAG SC 2.1.2)。 - 冗長な代替テキスト: 代替テキストで「〜の画像」や「〜の写真」を使用する(スクリーンリーダーはすでにロール「画像」を読み上げます)。
ベストプラクティスチェックリスト
- インタラクティブ要素が24x24px(Web)または44x44pt(ネイティブ)のターゲットサイズを満たしている。
- フォーカスインジケータが明確に見え、ハイコントラストである。
- モーダルが開いている間はフォーカスを閉じ込め、閉じるときにクリーンに解放する(
Escapeキーまたは閉じるボタン)。 - ドロップダウンとメニューは、閉じたときにトリガー要素にフォーカスを戻す。
- フォームがテキストベースのエラー提案を提供する。
- アイコンのみのボタンにはすべて、説明的なテキストラベルがある。
- テキストを拡大したときにコンテンツが適切にリフローする。
参考文献
- WCAG 2.2 ガイドライン
- WAI-ARIA オーサリングプラクティス
- iOS アクセシビリティプログラミングガイド
- iOS ヒューマンインターフェースガイドライン - アクセシビリティ
- Android アクセシビリティデベロッパーガイド
関連スキル
frontend-patternsdesign-systemliquid-glass-designswiftui-patterns