Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WebアクセシビリティをCI/CDで担保する ― axe DevTools × Playwri...

WebアクセシビリティをCI/CDで担保する ― axe DevTools × Playwright C#実践ガイド

WebアクセシビリティをCI/CDで担保する ― axe DevTools × Playwright C#実践ガイド
.NETラボ 勉強会 2026年3月
https://dotnetlab.connpass.com/event/378930/

Avatar for tomokusaba

tomokusaba

March 16, 2026
Tweet

More Decks by tomokusaba

Other Decks in Technology

Transcript

  1. 自己紹介 • コミュニティ活動を通じて知識を アップデートしています。 • 2022/08-2026 Microsoft MVP (Developer Technologies)

    • tomo_kusaba • ドラクエ大好き ドラクエ10のプレイ時間→ 1キャラ目:2671時間 2キャラ目:916時間 3キャラ目:791時間 4キャラ目:190時間(配信用)
  2. アクセシビリティの根幹 • 情報や機能への「別ルート」を確保するということ • 視覚に頼れないとき →スクリーンリーダー • 聴覚に頼れないとき →字幕・文字情報 •

    マウス操作が困難なとき →キーボード操作のみで完結 • 一つの手段が使えないときに別の手段がある状態を作る
  3. WCAG 2.2の全体像 • 4つの原則 原則 説明 知覚可能 情報とUIコンポーネントがユーザーに知覚可能な方法で提示されなければならないとい う原則です。視覚・聴覚に頼らなくてもコンテンツを把握できる代替手段を提供すること が求められます。

    操作可能 UIコンポーネントとナビゲーションが操作可能でなければならないという原則です。キー ボードのみでの操作や、十分な操作時間の確保、発作を引き起こさないコンテンツ設計な どが含まれます。 理解可能 情報とUIの操作が理解可能でなければならないという原則です。読みやすいテキスト、予 測可能なページ動作、入力を支援する機能などが該当します。 堅牢 コンテンツが支援技術を含む多様なユーザーエージェントによって確実に解釈できるほど 堅牢でなければならないという原則です。
  4. WCAG 2.2の全体像(ガイドライン レベルA) 達成基準 概要 1.1.1 非テキストコンテンツ すべての非テキストコンテンツにテキストの代替を提供する 1.2.1 音声のみ・映像のみ(収録済み)

    収録済みの音声・映像のみのメディアに代替を提供する 1.2.2 キャプション(収録済み) 収録済み音声コンテンツにキャプションを提供する 1.2.3 音声解説またはメディアの代替(収録済み) 収録済み映像に音声解説またはメディアの代替を提供する 1.3.1 情報および関係性 表示で伝達される情報・構造・関係性をプログラム的に決定可能にする 1.3.2 意味のある順序 コンテンツの正しい読み上げ順序をプログラム的に決定可能にする 1.3.3 感覚的な特徴 指示が形状・色・サイズ・位置・音のみに依存しない 1.4.1 色の使用 色だけを情報伝達の唯一の視覚的手段としない 1.4.2 音声の制御 自動再生される音声を停止・一時停止・音量調整可能にする 2.1.1 キーボード すべての機能をキーボードで操作可能にする
  5. WCAG 2.2の全体像(ガイドライン レベルA) 達成基準 概要 2.1.2 キーボードトラップなし キーボードフォーカスが特定のコンポーネントから移動できなくならない 2.1.4 文字キーのショートカット

    文字のみのキーボードショートカットを無効化・再割り当て可能にする 2.2.1 タイミング調整可能 時間制限がある場合にユーザーが調整可能にする 2.2.2 一時停止・停止・非表示 動き・点滅・スクロール・自動更新するコンテンツを制御可能にする 2.3.1 3回の閃光またはしきい値以下 1秒間に3回を超える閃光を含むコンテンツを含まない 2.4.1 ブロックスキップ 繰り返されるコンテンツブロックをスキップする手段を提供する 2.4.2 ページタイトル Webページにトピックや目的を説明するタイトルを設定する 2.4.3 フォーカス順序 フォーカス可能なコンポーネントが意味と操作性を保つ順序でフォーカスを受 け取る 2.4.4 リンクの目的(コンテキスト内) リンクテキストまたはその文脈からリンクの目的が判断可能にする 2.5.1 ポインタジェスチャ マルチポイント・パスベースのジェスチャを単一ポインタでも操作可能にする
  6. WCAG 2.2の全体像(ガイドライン レベルA) 達成基準 概要 2.5.2 ポインタのキャンセル 単一ポインタ操作のダウンイベントで即座に機能を実行しない 2.5.3 ラベルとアクセシブルネーム

    UIコンポーネントの視覚的ラベルがアクセシブルネームに含まれる 2.5.4 モーションによる操作 デバイスモーションで操作可能な機能にUIコンポーネントでの代替操作を提 供する 3.1.1 ページの言語 ページのデフォルト言語をプログラム的に決定可能にする 3.2.1 フォーカス時 フォーカスを受け取ったときにコンテキストの変化を開始しない 3.2.2 入力時 設定変更時にコンテキストの変化を自動的に発生させない 3.2.6 一貫したヘルプ ヘルプ機構がページ間で同じ相対的順序で提示される 3.3.1 エラーの特定 入力エラーが自動検出された場合にエラー項目を特定しテキストで説明する 3.3.2 ラベルまたは説明 ユーザー入力が必要な場合にラベルまたは説明を提供する 3.3.7 冗長な入力 同一プロセスで以前入力した情報を再入力させない 4.1.2 名前・役割・値 UIコンポーネントの名前と役割がプログラム的に決定可能である
  7. WCAG 2.2の全体像(ガイドライン レベルAA) 達成基準 概要 1.2.4 キャプション(ライブ) ライブ音声コンテンツにキャプションを提供する 1.2.5 音声解説(収録済み)

    収録済み映像コンテンツに音声解説を提供する 1.3.4 表示の向き コンテンツが特定の表示向きに制限されない 1.3.5 入力目的の特定 ユーザー情報を収集する入力フィールドの目的をプログラム的に決定可能に する 1.4.3 コントラスト(最低限) テキストと背景のコントラスト比が4.5:1以上(大きなテキストは3:1以上) 1.4.4 テキストのサイズ変更 テキストを200%まで拡大してもコンテンツや機能が損なわれない 1.4.5 文字画像 技術的に可能な場合は文字画像ではなくテキストを使用する 1.4.10 リフロー 320CSSピクセル幅(横スクロールコンテンツは256CSSピクセル高)で2方 向のスクロールを必要としない 1.4.11 非テキストのコントラスト UIコンポーネントとグラフィックのコントラスト比が3:1以上 1.4.12 テキストの間隔 行の高さ・段落間隔・文字間隔・単語間隔を調整してもコンテンツや機能が損 なわれない 1.4.13 ホバーまたはフォーカスで表示されるコン テンツ 追加コンテンツを解除可能・ホバー可能・持続的にする
  8. WCAG 2.2の全体像(ガイドライン レベルAA) 達成基準 概要 2.4.5 複数の手段 Webページセット内のページを見つける方法が複数提供される 2.4.6 見出しおよびラベル

    見出しとラベルがトピックまたは目的を説明する 2.4.7 フォーカスの可視性 キーボード操作可能なUIのフォーカスインジケータが視覚的に確認可能であ る 2.4.11 フォーカスの遮蔽防止(最低限) フォーカスを受けたコンポーネントが作成者のコンテンツにより完全に隠され ない 2.5.7 ドラッグ操作 ドラッグ操作を使用する機能にドラッグなしの代替手段を提供する 2.5.8 ターゲットサイズ(最低限) ポインタ入力のターゲットサイズが24×24CSSピクセル以上 3.1.2 部分的な言語 各文節やフレーズの言語をプログラム的に決定可能にする 3.2.3 一貫したナビゲーション ナビゲーションが複数ページで同じ相対的順序で繰り返される 3.2.4 一貫した識別 同じ機能を持つコンポーネントが一貫して識別される 3.3.3 エラーの修正候補 入力エラーが自動検出され修正候補が分かる場合はそれを提供する
  9. WCAG 2.2の全体像(ガイドライン レベルAA) 達成基準 概要 3.3.4 エラーの防止(法的・金銭的・データ) 法的義務等を伴うページでは操作の取り消し・検証・確認のいずれかを提供す る 3.3.8

    アクセシブルな認証(最低限) 認証プロセスで認知機能テストを要求しない(代替手段またはメカニズムを提 供) 4.1.3 ステータスメッセージ ステータスメッセージをrole等でプログラム的に決定可能にする
  10. WCAG 2.2の全体像(ガイドライン レベルAAA) 達成基準 概要 1.2.6 手話(収録済み) 収録済み音声コンテンツに手話通訳を提供する 1.2.7 拡張音声解説(収録済み)

    映像の前景音声の間に十分な間合いがない場合に拡張音声解説を提供する 1.2.8 メディアの代替(収録済み) 収録済み同期メディア・映像のみのメディアに代替を提供する 1.2.9 音声のみ(ライブ) ライブ音声コンテンツに同等情報の代替を提供する 1.3.6 目的の特定 UIコンポーネント・アイコン・リージョンの目的をプログラム的に決定可能にす る 1.4.6 コントラスト(強化) テキストと背景のコントラスト比が7:1以上(大きなテキストは4.5:1以上) 1.4.7 背景音が小さいまたは無し 前景音声に対して背景音を20dB以上低くする 1.4.8 視覚的な表現 テキストの前景色・背景色・行幅・配置・行間・サイズをユーザーが調整可能にす る 1.4.9 文字画像(例外なし) 純粋な装飾または本質的な場合を除き文字画像を使用しない 2.1.3 キーボード(例外なし) すべての機能がキーボードで特定のタイミングなしに操作可能である
  11. WCAG 2.2の全体像(ガイドライン レベルAAA) 達成基準 概要 2.2.3 タイミング不要 タイミングがコンテンツに必須の要素ではない 2.2.4 中断

    緊急時を除きユーザーが中断を延期・抑制可能にする 2.2.5 再認証 認証セッション期限切れ後にデータを失わずに活動を継続可能にする 2.2.6 タイムアウト データ損失の原因となるタイムアウトを事前に警告する 2.3.2 3回の閃光 1秒間に3回を超えて閃光するコンテンツを含まない 2.3.3 インタラクションによるアニメーション インタラクションで発生するモーションアニメーションを無効化可能にする 2.4.8 現在位置 ページセット内におけるユーザーの現在位置情報を提供する 2.4.9 リンクの目的(リンクのみ) リンクテキストのみからリンクの目的を特定可能にする 2.4.10 セクション見出し セクション見出しでコンテンツを構成する 2.4.12 フォーカスの遮蔽防止(強化) フォーカスを受けたコンポーネントのいかなる部分も隠されない
  12. WCAG 2.2の全体像(ガイドライン レベルAAA) 達成基準 概要 2.4.13 フォーカスの外観 フォーカスインジケータが十分な面積とコントラストを持つ 2.5.5 ターゲットサイズ(強化)

    ポインタ入力のターゲットサイズが44×44CSSピクセル以上 2.5.6 同時入力メカニズム プラットフォームで利用可能な入力モダリティの使用を制限しない 3.1.3 珍しい用語 特殊な意味で使用される用語の定義を特定する仕組を提供する 3.1.4 略語 略語の展開形式や意味を特定する仕組を提供する 3.1.5 読解レベル 中学校教育修了レベルを超える読解力を要するテキストに補足コンテンツを 提供する 3.1.6 発音 文脈上意味が曖昧になる単語の発音を特定する仕組を提供する 3.2.5 要求による変化 コンテキストの変化はユーザーの要求によってのみ開始される 3.3.5 ヘルプ コンテキストに応じたヘルプを利用可能にする 3.3.6 エラーの防止(すべて) ユーザーが情報を送信するすべてのページで取り消し・検証・確認のいずれか を提供する 3.3.9 アクセシブルな認証(強化) 認証プロセスで認知機能テストを要求しない(オブジェクト認識・個人コンテン ツの例外なし)
  13. 自動テストと手動テスト • 自動テストの例 • Axe DevToolsでCIを回す • Lighthouseツールでアクセシビリティスコアとレポートを生成する • 手動テストの例

    • キーボード移動で操作のつまりやフォーカスの欠落を確認 • 画面幅を小さくしたりレイアウト崩れや可読性を確認 • スクリーンリーダーで読み上げ順序・意味・状態が伝わるかを確認 • 音声認識やハイコントラストモードでも操作が破綻しないかを確認 • 言語理解・コンテキスト理解ができるかどうかの確認
  14. WCAG 2.2のテスト(ガイドライン レベルA) 達成基準 自動テスト 手動テスト 1.1.1 非テキストコンテンツ 部分的に可能 必須

    1.2.1 音声のみ・映像のみ(収録済み) 不可能 必須 1.2.2 キャプション(収録済み) 限定的 必須 1.2.3 音声解説またはメディアの代替(収録済み) 不可能 必須 1.3.1 情報および関係性 部分的に可能 必須 1.3.2 意味のある順序 限定的 必須 1.3.3 感覚的な特徴 不可能 必須 1.4.1 色の使用 限定的 必須 1.4.2 音声の制御 限定的 必須 2.1.1 キーボード 限定的 必須
  15. WCAG 2.2のテスト(ガイドライン レベルA) 達成基準 自動テスト 手動テスト 2.1.2 キーボードトラップなし 限定的 必須

    2.1.4 文字キーのショートカット 不可能 必須 2.2.1 タイミング調整可能 不可能 必須 2.2.2 一時停止・停止・非表示 限定的 必須 2.3.1 3回の閃光またはしきい値以下 部分的 必須 2.4.1 ブロックスキップ 部分的 必須 2.4.2 ページタイトル 可能 必須 2.4.3 フォーカス順序 限定的 必須 2.4.4 リンクの目的(コンテキスト内) 部分的 必須 2.5.1 ポインタジェスチャ 不可能 必須
  16. WCAG 2.2のテスト(ガイドライン レベルA) 達成基準 自動テスト 手動テスト 2.5.2 ポインタのキャンセル 不可能 必須

    2.5.3 ラベルとアクセシブルネーム 部分的 必須 2.5.4 モーションによる操作 不可能 必須 3.1.1 ページの言語 可能 推奨 3.2.1 フォーカス時 不可能 必須 3.2.2 入力時 不可能 必須 3.2.6 一貫したヘルプ 不可能 必須 3.3.1 エラーの特定 限定的 必須 3.3.2 ラベルまたは説明 部分的 必須 3.3.7 冗長な入力 不可能 必須 4.1.2 名前・役割・値 部分的 必須
  17. WCAG 2.2のテスト(ガイドライン レベルAA) 達成基準 自動テスト 手動テスト 1.2.4 キャプション(ライブ) 不可能 必須

    1.2.5 音声解説(収録済み) 限定的 必須 1.3.4 表示の向き 不可能 必須 1.3.5 入力目的の特定 部分的 必須 1.4.3 コントラスト(最低限) 多くのケースで可能 必須 1.4.4 テキストのサイズ変更 不可能 必須 1.4.5 文字画像 限定的 必須 1.4.10 リフロー 限定的 必須 1.4.11 非テキストのコントラスト 限定的 必須 1.4.12 テキストの間隔 不可能 必須 1.4.13 ホバーまたはフォーカスで表示されるコンテンツ 不可能 必須
  18. WCAG 2.2のテスト(ガイドライン レベルAA) 達成基準 自動テスト 手動テスト 2.4.5 複数の手段 不可能 必須

    2.4.6 見出しおよびラベル 部分的 必須 2.4.7 フォーカスの可視性 部分的 必須 2.4.11 フォーカスの遮蔽防止(最低限) 不可能 必須 2.5.7 ドラッグ操作 不可能 必須 2.5.8 ターゲットサイズ(最低限) 部分的 必須 3.1.2 部分的な言語 限定的 必須 3.2.3 一貫したナビゲーション 不可能 必須 3.2.4 一貫した識別 不可能 必須 3.3.3 エラーの修正候補 不可能 必須
  19. WCAG 2.2のテスト(ガイドライン レベルAA) 達成基準 自動テスト 手動テスト 3.3.4 エラーの防止(法的・金銭的・データ) 不可能 必須

    3.3.8 アクセシブルな認証(最低限) 限定的 必須 4.1.3 ステータスメッセージ 部分的 必須
  20. WCAG 2.2のテスト(ガイドライン レベルAAA) 達成基準 自動テスト 手動テスト 1.2.6 手話(収録済み) 不可能 必須

    1.2.7 拡張音声解説(収録済み) 不可能 必須 1.2.8 メディアの代替(収録済み) 不可能 必須 1.2.9 音声のみ(ライブ) 不可能 必須 1.3.6 目的の特定 限定的 必須 1.4.6 コントラスト(強化) 多くのケースで可能 必須 1.4.7 背景音が小さいまたは無し 不可能 必須 1.4.8 視覚的な表現 限定的 必須 1.4.9 文字画像(例外なし) 不可能 必須 2.1.3 キーボード(例外なし) 限定的 必須
  21. WCAG 2.2のテスト(ガイドライン レベルAAA) 達成基準 自動テスト 手動テスト 2.2.3 タイミング不要 不可能 必須

    2.2.4 中断 不可能 必須 2.2.5 再認証 不可能 必須 2.2.6 タイムアウト 不可能 必須 2.3.2 3回の閃光 部分的に可能 必須 2.3.3 インタラクションによるアニメーション 限定的に可能 必須 2.4.8 現在位置 限定的 必須 2.4.9 リンクの目的(リンクのみ) 部分的に可能 必須 2.4.10 セクション見出し 部分的に可能 必須 2.4.12 フォーカスの遮蔽防止(強化) 不可能 必須
  22. WCAG 2.2のテスト(ガイドライン レベルAAA) 達成基準 自動テスト 手動テスト 2.4.13 フォーカスの外観 限定的 必須

    2.5.5 ターゲットサイズ(強化) 部分的 必須 2.5.6 同時入力メカニズム 不可能 必須 3.1.3 珍しい用語 不可能 必須 3.1.4 略語 限定的 必須 3.1.5 読解レベル 限定的 必須 3.1.6 発音 不可能 必須 3.2.5 要求による変化 不可能 必須 3.3.5 ヘルプ 不可能 必須 3.3.6 エラーの防止(すべて) 不可能 必須 3.3.9 アクセシブルな認証(強化) 限定的 必須
  23. テストコード(抜粋) public static TheoryData<string, string> TargetPages => new() { {

    "/", "Home" }, { "/counter", "Counter" }, { "/weather", "Weather" }, }; [Theory] [MemberData(nameof(TargetPages))] public async Task Page_ShouldHaveNoAccessibilityViolations(string path, string pageName) { // 1. ページに遷移 await _page.GotoAsync($"{_baseUrl}{path}"); await _page.WaitForLoadStateAsync(LoadState.NetworkIdle); // 2. axe-coreでアクセシビリティ検査を実行 var options = new AxeRunOptions { RunOnly = new RunOnlyOptions { Type = "tag", Values = ["wcag2a", "wcag2aa", "wcag21aa"] } }; var result = await _page.RunAxe(options); // 3. 違反があればテストを失敗させる if (result.Violations.Length > 0) { var message = FormatViolations(pageName, path, result.Violations); Assert.Fail(message); } }
  24. ワークフロー例 • https://github.com/tomokusaba/BlazorA11yDemo/ blob/main/.github/workflows/azure-static-web- apps.yml • dotnet publishを実行してnpx serveで簡易HTTPサーバを 起動

    Playwrightを使ったアクセシビリティテストを実施 • アクセシビリティテストに失敗してもワークフローは止めずに結果 をサマリー出力 • テスト結果とデプロイ対象をアーティファクトに保存 • DeployジョブでAzure Static Web Appsへデプロイ