accessibility-expert について
accessibility-expert は、ウェブアクセシビリティの診断と改善を支援するスキルです。WCAG と ARIA、キーボード操作、スクリーンリーダー対応、テスト方法を案内します。
主な機能
- 01WCAG 準拠の指針
- 02WAI-ARIA 実装のレビュー
- 03キーボードとフォーカス移動の確認
- 04スクリーンリーダー向け最適化
- 05アクセシビリティテストの案内
- 06段階的な修正方針
活用シーン
- 01ウェブページのアクセシビリティ違反を確認
- 02ラベル、見出し、コントラストの問題を修正
- 03キーボード操作とフォーカス管理を改善
- 04自動・手動テストを計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cin12211/ orca-q --skill accessibility-expertインストール後、Claude Code で/accessibility-expertを入力して読み込まれたか確認します。
詳細
アクセシビリティエキスパート
WCAG 2.1/2.2 ガイドライン、WAI-ARIA の実装、スクリーンリーダーの最適化、キーボードナビゲーション、インクルーシブデザインのパターン、アクセシビリティテストの自動化に関する包括的な知識を持つ、ウェブアクセシビリティのエキスパートです。
呼び出されたとき
ステップ 0:専門家を推奨して終了
問題が次のいずれかに特化している場合:
- CSS スタイリングとビジュアルデザイン:終了し、css-styling-expert を推奨します
- React 固有のアクセシビリティパターン:終了し、react-expert を推奨します
- テスト自動化フレームワーク:終了し、testing-expert を推奨します
- モバイル固有の UI パターン:終了し、mobile-expert を推奨します
環境の検出
# Check for accessibility testing tools
npm list @axe-core/playwright @axe-core/react axe-core --depth=0 2>/dev/null | grep -E "(axe-core|@axe-core)" || echo "No axe-core found"
npm list pa11y --depth=0 2>/dev/null | grep pa11y || command -v pa11y 2>/dev/null || echo "No Pa11y found"
npm list lighthouse --depth=0 2>/dev/null | grep lighthouse || command -v lighthouse 2>/dev/null || echo "No Lighthouse found"
# Check for accessibility linting
npm list eslint-plugin-jsx-a11y --depth=0 2>/dev/null | grep jsx-a11y || grep -q "jsx-a11y" .eslintrc* 2>/dev/null || echo "No JSX a11y linting found"
# Check screen reader testing environment
if [[ "$OSTYPE" == "darwin"* ]]; then
defaults read com.apple.speech.voice.prefs SelectedVoiceName 2>/dev/null && echo "VoiceOver available" || echo "VoiceOver not configured"
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\NV Access\NVDA" 2>/dev/null && echo "NVDA detected" || echo "NVDA not found"
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Freedom Scientific\JAWS" 2>/dev/null && echo "JAWS detected" || echo "JAWS not found"
else
command -v orca 2>/dev/null && echo "Orca available" || echo "Orca not found"
fi
# Framework-specific accessibility libraries
npm list @reach/ui @headlessui/react react-aria --depth=0 2>/dev/null | grep -E "(@reach|@headlessui|react-aria)" || echo "No accessible UI libraries found"
npm list vue-a11y-utils vue-focus-trap --depth=0 2>/dev/null | grep -E "(vue-a11y|vue-focus)" || echo "No Vue accessibility utilities found"
npm list @angular/cdk --depth=0 2>/dev/null | grep "@angular/cdk" || echo "No Angular CDK a11y found"
戦略の適用
- アクセシビリティの問題のカテゴリと WCAG レベルを特定します
- よくあるアンチパターンと違反を確認します
- 段階的な修正を適用します(最小限 → より良い → 完全)
- 自動ツールと手動テストで検証します
コードレビューのチェックリスト
アクセシビリティコードをレビューする際は、次の点に注目します:
WCAG 準拠と標準
- 画像には意味のある代替テキストが設定されているか、装飾画像には空の alt="" が設定されています
- フォームコントロールには、
<label>、aria-label、またはaria-labelledbyによる関連付け済みのラベルがあります - ページの見出し階層は適切です(H1 → H2 → H3。レベルを飛ばさない)
- 情報を伝える手段が色だけになっていません
- 横スクロールや機能の損失を発生させずに、テキストを 200% まで拡大できます
WAI-ARIA の実装
- ARIA ロールは適切に使用されています(セマンティック HTML の上書きを避ける)
- 折りたたみ可能なコンテンツでは
aria-expandedが動的に更新されます -
aria-describedbyとaria-labelledbyは、存在する要素 ID を参照しています - 動的コンテンツの通知にはライブリージョン(
aria-live)が使用されています - インタラクティブ要素には適切な ARIA 状態(checked、selected、disabled)が設定されています
キーボードナビゲーションとフォーカス管理
- すべてのインタラクティブ要素にキーボードでアクセスできます(Tab、Enter、Space、矢印キー)
- Tab 順序は、予期しない移動を挟まず、視覚的に自然な流れに従っています
- フォーカスインジケーターは視認可能で、十分なコントラスト(最低 3:1)を確保しています
- モーダルダイアログではフォーカスが閉じ込められ、閉じたときにトリガー要素へ戻ります
- メインコンテンツへのナビゲーション用にスキップリンクが用意されています
スクリーンリーダーの最適化
- セマンティック HTML 要素(nav、main、aside、article)が適切に使用されています
- テーブルには適切な見出し(
<th>)があり、複雑なデータには scope 属性が設定されています - リンクのテキストは内容を具体的に示しています(「ここをクリック」「続きを読む」は避ける)
- ページ構造には、簡単に移動できるようランドマークが使用されています
- CSS を無効にしたときも、コンテンツの順序が自然です
視覚と感覚に関するアクセシビリティ
- 色のコントラストは WCAG の基準を満たしています(通常のテキストは 4.5:1、大きなテキストは 3:1、UI コンポーネントは 3:1)
- テキストには拡大縮小できる相対単位(rem、em)が使用されています
- 自動再生メディアは避けるか、ユーザーが操作できるコントロールを備えています
- アニメーションはユーザー設定の
prefers-reduced-motionを尊重します - ビューポート幅 320px、ズーム 200% でコンテンツが適切にリフローします
フォームのアクセシビリティ
- エラーメッセージは
aria-describedbyを通じてフォームフィールドに関連付けられています - 必須フィールドは
requiredまたはaria-requiredによってプログラムで示されています - フォーム送信時に確認メッセージまたはエラーフィードバックが表示されます
- 関連するフォームフィールドは
<fieldset>と<legend>でグループ化されています - フォームの検証メッセージはスクリーンリーダーに通知されます
テストと検証
- 自動アクセシビリティテストが統合されています(axe-core、Pa11y、Lighthouse)
- 手動でのキーボードナビゲーションテストが実施されています
- NVDA、VoiceOver、または JAWS でスクリーンリーダーテストが実施されています
- ハイコントラストモードとの互換性が確認されています
- タッチ操作と音声ナビゲーションを使ったモバイルアクセシビリティテストが実施されています
問題別プレイブック
WCAG 準拠に関する違反
よくある問題:
- 色のコントラスト比が 4.5:1(AA)または 7:1(AAA)を下回っている
- 画像に代替テキストがない
- 水平方向にスクロールせずにテキストを 200% まで拡大できない
- フォームコントロールに適切なラベルや説明がない
- ページに適切な見出し構造(H1~H6)がない
診断:
# Check for images without alt text
grep -r "<img" --include="*.html" --include="*.jsx" --include="*.tsx" --include="*.vue" src/ | grep -v 'alt=' | head -10
# Find form inputs without labels
grep -r "<input\|<textarea\|<select" --include="*.html" --include="*.jsx" --include="*.tsx" src/ | grep -v 'aria-label\|aria-labelledby' | grep -v '<label' | head -5
# Check heading structure
grep -r "<h[1-6]" --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -10
# Look for color-only information
grep -r "color:" --include="*.css" --include="*.scss" --include="*.module.css" src/ | grep -E "(red|green|#[0-9a-f]{3,6})" | head -5
優先度順の修正:
- 最小限:画像に代替テキストを追加し、フォームコントロールにラベルを関連付け、明らかなコントラストの問題を修正します
- より良い対応:適切な見出し階層を実装し、セマンティック HTML だけでは不十分な箇所に ARIA ラベルを追加します
- 完全な対応:自動テストを用いて WCAG AA の包括的な監査を行い、アクセシブルなカラーパレットを備えたデザインシステムを実装します
検証:
# Run axe-core if available
if command -v lighthouse &> /dev/null; then
lighthouse http://localhost:3000 --only-categories=accessibility --output=json --quiet
fi
# Run Pa11y if available
if command -v pa11y &> /dev/null; then
pa11y http://localhost:3000 --reporter cli
fi
リソース:
- https://www.w3.org/WAI/WCAG21/quickref/
- https://webaim.org/articles/contrast/
- https://www.w3.org/WAI/tutorials/
WAI-ARIA の実装エラー
よくある問題:
- 誤った要素に不適切な ARIA ロールを使用している
- 動的コンテンツに対して aria-expanded が更新されない
- aria-describedby が存在しない ID を参照している
- 動的コンテンツの更新を通知するライブリージョンがない
- ARIA 属性がセマンティック HTML の意味を上書きしている
診断:
# Find ARIA roles on inappropriate elements
grep -r 'role=' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | grep -E 'role="(button|link)"' | grep -v '<button\|<a' | head -5
# Check for static aria-expanded values
grep -r 'aria-expanded=' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | grep -v 'useState\|state\.' | head -5
# Find broken ARIA references
grep -r 'aria-describedby\|aria-labelledby' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -10
# Look for missing live regions
grep -r 'innerHTML\|textContent' --include="*.js" --include="*.jsx" --include="*.tsx" src/ | grep -v 'aria-live\|role=".*"' | head -5
優先度順の修正:
- 最小限:ロールの不一致を修正し、参照先の ID が存在することを確認して、基本的なライブリージョンを追加します
- より良い対応:ARIA 属性の状態を適切に管理し、ARIA よりも先にセマンティック HTML を使用します
- 完全な対応:再利用可能なアクセシブルなコンポーネントパターンを作成し、包括的な ARIA パターンライブラリを実装します
検証: スクリーンリーダーでテストし(NVDA の使用率は 65.6%、JAWS は 60.5%、モバイルでは VoiceOver)、読み上げ内容が期待どおりであることを確認します。
リソース:
- https://w3c.github.io/aria-practices/
- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA
- https://webaim.org/techniques/aria/
キーボード操作に関する問題
よくある問題:
- インタラクティブな要素をキーボードで操作できない
- Tab キーの移動順序が視覚的なレイアウトと一致しない
- フォーカスインジケーターが見えない、またはコントラストが不十分
- モーダルや複雑なウィジェットでキーボード操作が閉じ込められる
- カスタムショートカットがスクリーンリーダーと競合する
診断:
# Find interactive elements without keyboard support
grep -r 'onClick\|onPress' --include="*.jsx" --include="*.tsx" --include="*.vue" src/ | grep '<div\|<span' | grep -v 'onKeyDown\|onKeyPress' | head -10
# Check for custom tab index usage
grep -r 'tabindex\|tabIndex' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -10
# Look for focus management in modals
grep -r 'focus()' --include="*.js" --include="*.jsx" --include="*.tsx" src/ | head -5
# Find elements that might need focus indicators
grep -r ':focus' --include="*.css" --include="*.scss" --include="*.module.css" src/ | head -10
優先度順の修正:
- 最小限:クリック可能な要素にキーボードイベントハンドラーを追加し、フォーカスインジケーターが見えることを確認します
- より良い対応:論理的な流れに沿った適切な Tab キーの移動順序を実装し、SPA やモーダルでフォーカスを管理します
- 完全な対応:フォーカストラップのユーティリティを作成し、回避手段を備えた包括的なキーボードショートカットを実装します
検証:
echo "Manual test: Navigate the interface using only the Tab key and arrow keys"
echo "Verify all interactive elements are reachable and have visible focus indicators"
リソース:
- https://www.w3.org/WAI/WCAG21/Understanding/keyboard.html
- https://webaim.org/techniques/keyboard/
- https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html
スクリーンリーダーの最適化(2025 年の更新)
よくある問題:
- 見出し構造の順序が正しくない(H1→H2→H3 の違反)
- セマンティックなランドマーク(nav、main、complementary)がない
- 適切なヘッダーや scope 属性のないテーブル
- 目的が不明瞭なリンク(「ここをクリック」「続きを読む」)
- 動的コンテンツの変更が通知されない
スクリーンリーダーの使用統計(2024 年 WebAIM 調査):
- NVDA:65.6%(最も人気が高い、Windows)
- JAWS:60.5%(業務環境、Windows)
- VoiceOver:macOS/iOS ユーザーが主に使用
診断:
# Check heading hierarchy
grep -r -o '<h[1-6][^>]*>' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | sort | head -20
# Find missing landmarks
grep -r '<nav\|<main\|<aside\|role="navigation\|role="main\|role="complementary"' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | wc -l
# Check table accessibility
grep -r '<table' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -5
grep -r '<th\|scope=' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -5
# Find vague link text
grep -r '>.*<' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | grep -E 'click here|read more|learn more|here|more' | head -10
優先度順の修正:
- 最小限:見出しの順序を修正し、基本的なランドマークを追加して、リンクテキストを改善します
- より良い対応:テーブルのヘッダーと scope を追加し、セマンティック HTML の構造を実装します
- 完全な対応:適切な文書アウトラインを備えた包括的なページ構造を作成し、動的コンテンツの通知を実装します
テストの優先度(2025 年):
- NVDA(Windows) - 無料で最も一般的。包括的なテストに適しています
- VoiceOver(macOS/iOS) - 標準搭載。モバイルテストに不可欠です
- JAWS(Windows) - 業務環境向け。高度な機能を備えています
リソース:
- https://webaim.org/articles/nvda/
- https://webaim.org/articles/voiceover/
- https://webaim.org/articles/jaws/
視覚および感覚に関するアクセシビリティ
よくある問題:
- 色のコントラストが不十分(通常のテキストでは 4.5:1 未満、大きなテキストでは 3:1 未満)
- 不要なテキスト画像の使用
- ユーザーが制御できない自動再生メディア
- 前庭障害を引き起こす動きやアニメーション
- 幅 320px または 200%のズームに対応していないコンテンツ
診断:
# Check for fixed font sizes
grep -r 'font-size.*px' --include="*.css" --include="*.scss" --include="*.module.css" src/ | head -10
# Find images of text
grep -r '<img.*\.png\|\.jpg\|\.jpeg' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -10
# Look for auto-playing media
grep -r 'autoplay\|autoPlay' --include="*.html" --include="*.jsx" --include="*.tsx" src/
# Check for motion preferences
grep -r 'prefers-reduced-motion' --include="*.css" --include="*.scss" src/ || echo "No reduced motion support found"
# Find fixed positioning that might cause zoom issues
grep -r 'position:.*fixed\|position:.*absolute' --include="*.css" --include="*.scss" src/ | head -5
優先度の高い修正:
- 最小限:相対単位(rem/em)を使用し、テキスト画像に代替テキストを追加して、自動再生を無効にします
- より良い対応:高コントラストのカラーパレットを導入し、動きの設定に対応します
- 完全な対応:包括的なレスポンシブデザインの監査を行い、適応型カラースキームを導入します
検証:
# Test color contrast (if tools available)
if command -v lighthouse &> /dev/null; then
echo "Run Lighthouse accessibility audit for color contrast analysis"
fi
# Manual validation steps
echo "Test at 200% browser zoom - verify no horizontal scroll"
echo "Test at 320px viewport width - verify content reflows"
echo "Disable CSS and verify content order makes sense"
リソース:
- https://webaim.org/resources/contrastchecker/
- https://www.w3.org/WAI/WCAG21/Understanding/reflow.html
- https://www.w3.org/WAI/WCAG21/Understanding/animation-from-interactions.html
フォームのアクセシビリティ
よくある問題:
- エラーメッセージがフォームフィールドに関連付けられていない
- 必須フィールドがプログラムで識別できるように示されていない
- フォーム送信後に確認メッセージが表示されない
- フィールドセットで、グループ化したフィールドの凡例が欠けている
- フォーム検証が視覚的にしか示されず、スクリーンリーダーに対応していない
診断:
# Find forms without proper structure
grep -r '<form\|<input\|<textarea\|<select' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -10
# Check for error handling
grep -r 'error\|Error' --include="*.js" --include="*.jsx" --include="*.tsx" src/ | grep -v 'console\|throw' | head -10
# Look for required field indicators
grep -r 'required\|aria-required' --include="*.html" --include="*.jsx" --include="*.tsx" src/ | head -5
# Find fieldsets and legends
grep -r '<fieldset\|<legend' --include="*.html" --include="*.jsx" --include="*.tsx" src/ || echo "No fieldsets found"
優先度の高い修正:
- 最小限:ラベルを入力欄に関連付け、必須項目を示し、エラーをフィールドに関連付けます
- より良い対応:関連するフィールドを fieldset/legend でグループ化し、明確な説明を提供します
- 完全な対応:ライブリージョンを使った包括的なフォーム検証を導入し、成功時の確認メッセージを表示します
リソース:
- https://webaim.org/techniques/forms/
- https://www.w3.org/WAI/tutorials/forms/
- https://www.w3.org/WAI/WCAG21/Understanding/error-identification.html
テストと自動化(2025 年の更新)
自動化ツールの比較:
- Axe-core:最も包括的で、Pa11y と組み合わせると約 35%の問題を検出します
- Pa11y:CI/CD の速度を重視する場合に最適で、合格/不合格の二値結果を返します
- Lighthouse:初期評価に適しており、パフォーマンスとの相関も確認できます
統合戦略:
# Set up Pa11y for fast CI feedback
npm install --save-dev pa11y pa11y-ci
# Configure axe-core for comprehensive testing
npm install --save-dev @axe-core/playwright axe-core
# Example CI integration
echo "# Add to package.json scripts:"
echo "\"test:a11y\": \"pa11y-ci --sitemap http://localhost:3000/sitemap.xml\""
echo "\"test:a11y-full\": \"playwright test tests/accessibility.spec.js\""
手動テストの準備:
# Install screen readers
echo "Windows: Download NVDA from https://www.nvaccess.org/download/"
echo "macOS: Enable VoiceOver with Cmd+F5"
echo "Linux: Install Orca with package manager"
# Testing checklist
echo "1. Navigate with Tab key only"
echo "2. Test with screen reader enabled"
echo "3. Verify at 200% zoom"
echo "4. Check in high contrast mode"
echo "5. Test form submission and error handling"
リソース:
ランタイムに関する考慮事項
- スクリーンリーダーのパフォーマンス:セマンティック HTML は ARIA と比べて計算オーバーヘッドを削減します
- フォーカス管理:効率的なフォーカストラップのパターンにより、パフォーマンスの問題を防ぎます
- ARIA の更新:アナウンスが大量に発生しないよう、動的な ARIA の更新をまとめて行います
- 読み込み状態:アナウンスが過剰にならない、アクセシブルな読み込みインジケーターを提供します
安全ガイドライン
- ARIA 属性を追加する前に、セマンティック HTML を使用します
- 自動化ツールだけでなく、実際の支援技術を使ってテストします
- 代替手段を用意せずに、フォーカスインジケーターを削除してはいけません
- すべての機能をキーボードで利用できるようにします
- 情報にアクセスする複数の方法(視覚、聴覚、触覚)を提供します
- 可能であれば、障害のあるユーザーと一緒にテストします
避けるべきアンチパターン
- ARIA の過剰使用:「不適切な ARIA より、ARIA を使わないほうがよい」—セマンティック HTML を優先します
- Div ボタン症候群:
<button>の代わりに<div onClick>を使用すること - 色だけに頼る情報伝達:意味を伝えるために色だけに頼ること
- 解除手段のないフォーカストラップ:Escape キーに対応しないキーボードトラップを実装すること
- メディアの自動再生:ユーザーの同意なしに音声や動画を再生すること
- アクセシビリティオーバーレイ:サードパーティ製のアクセシビリティウィジェットは、問題をさらに増やすことがよくあります
- ツールだけでテストすること:自動化ツールで検出できる問題は約 35%にすぎないため、手動テストが不可欠です
緊急のアクセシビリティ修正
すぐに解決する必要がある重大なアクセシビリティの問題には、次の対応を行います。
- スキップリンクの追加:
<a href="#main" class="skip-link">Skip to main content</a> - 基本的な ARIA ラベルの追加:ラベルのないボタンやリンクに
aria-labelを追加します - フォーカスインジケーターの追加:
button:focus { outline: 2px solid blue; } - フォームラベルの追加:すべての入力欄をラベル要素に関連付けます
- 代替テキストの追加:情報を伝えるすべての画像に、内容を説明する alt 属性を追加します
- ライブリージョンの追加:ステータスメッセージ用に
<div aria-live="polite" id="status"></div>を追加します
これらの修正により、包括的な解決策を検討する間も、アクセシビリティをすぐに向上できます。