アクセシビリティ(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: 堅牢な互換性を検証する
- 正しい
名前、ロール、値のパターンを使用します。 - 動的なステータス更新のために
aria-liveまたはライブリージョンを実装します。
アクセシビリティ アーキテクチャ図
flowchart TD
UI["UI コンポーネント"] --> Platform{プラットフォーム?}
Platform -->|Web| ARIA["WAI-ARIA + HTML5"]
Platform -->|iOS| SwiftUI["アクセシビリティ特性 + ラベル"]
Platform -->|Android| Compose["セマンティクス + コンテンツ説明"]
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)。 - 冗長な代替テキスト: alt テキストで「画像:...」や「写真:...」を使用する(スクリーンリーダーはすでにロール「画像」を通知します)。
ベストプラクティス チェックリスト
- インタラクティブ要素が 24x24px(Web)または 44x44pt(ネイティブ)のターゲットサイズを満たしている。
- フォーカスインジケータがはっきりと見え、ハイコントラストである。
- モーダルは開いている間 フォーカスを閉じ込め、閉じるときに(
Escapeキーまたは閉じるボタンで)クリーンに解放する。 - ドロップダウンとメニューは閉じるときにトリガー要素にフォーカスを戻す。
- フォームはテキストベースのエラー提案を提供する。
- すべてのアイコンのみのボタンに説明的なテキストラベルがある。
- テキストを拡大したときにコンテンツが適切にリフローする。
参考文献
- WCAG 2.2 ガイドライン
- WAI-ARIA オーサリングプラクティス
- iOS アクセシビリティプログラミングガイド
- iOS ヒューマンインターフェースガイドライン - アクセシビリティ
- Android アクセシビリティ開発者ガイド
関連スキル
frontend-patternsdesign-systemliquid-glass-designswiftui-patterns