accessibility-auditor について
accessibility-auditor は、Web のアクセシビリティを監査・改善するチーム向けのガイダンスです。WCAG の実践、よくある問題の修正、ARIA、自動・キーボード・スクリーンリーダーによるテストを説明します。
主な機能
- 01WCAG 2.1 のガイダンス
- 02よくある問題の修正
- 03ARIA 属性とランドマーク
- 04自動テストのチェックリスト
- 05キーボード操作のテスト
- 06スクリーンリーダーのテスト
活用シーン
- 01WCAG に沿ったサイト監査
- 02ラベルや代替テキストの修正
- 03キーボードのみでの操作確認
- 04スクリーンリーダーでのページ検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ davila7/ claude-code-templates --skill accessibility-auditorインストール後、Claude Code で/accessibility-auditorを入力して読み込まれたか確認します。
詳細
アクセシビリティ監査ツール
WCAG 標準に準拠し、あらゆる能力のユーザーに効果的に対応する、アクセシブルな Web 体験を作成するための包括的なガイドです。
このスキルを使用するタイミング
次の場合にこのスキルを使用してください:
- Web サイトのアクセシビリティ準拠を監査するとき
- WCAG 2.1 レベル AA または AAA 基準を実装するとき
- アクセシビリティの違反やエラーを修正するとき
- スクリーンリーダー(NVDA、JAWS、VoiceOver)でテストするとき
- キーボードナビゲーションが正しく動作することを確認するとき
- ARIA 属性とランドマークを実装するとき
- ADA または Section 508 準拠の監査に備えるとき
- インクルーシブなユーザー体験を設計するとき
WCAG 2.1 の原則(POUR)
1. 知覚可能(Perceivable)
ユーザーは提示される情報を知覚できる必要があります。
2. 操作可能(Operable)
ユーザーはインターフェースを操作できる必要があります。
3. 理解可能(Understandable)
ユーザーは情報とインターフェースを理解できる必要があります。
4. 堅牢(Robust)
コンテンツは、現在および将来の技術で動作するのに十分な堅牢性を持つ必要があります。
よくあるアクセシビリティの問題と修正方法
1. 画像の代替テキストの欠落
❌ 問題:
<img src="/products/shoes.jpg">
✅ 解決策:
<img src="/products/shoes.jpg" alt="Red Nike Air Max running shoes with white swoosh">
<img src="/decorative-pattern.svg" alt="" role="presentation">
<a href="/">
<img src="/logo.png" alt="Company Name - Home">
</a>
ルール:
- 情報を伝える画像: 内容や機能を説明する
- 装飾的な画像: 空の alt(alt="")を使用する
- 機能的な画像: 操作内容を説明する
- 複雑な画像: 近くに詳細な説明を用意する
2. 低いカラーコントラスト
❌ 問題:
/* Contrast ratio 2.5:1 - Fails WCAG */
.text {
color: #767676;
background: #ffffff;
}
✅ 解決策:
/* Contrast ratio 4.5:1+ - Passes AA */
.text {
color: #595959;
background: #ffffff;
}
/* Contrast ratio 7:1+ - Passes AAA */
.text-high-contrast {
color: #333333;
background: #ffffff;
}
要件:
- 通常のテキスト(18px 未満): 最低 4.5:1(AA)、強化 7:1(AAA)
- 大きいテキスト(18px 以上または 14px 以上の太字): 最低 3:1(AA)、強化 4.5:1(AAA)
- UI コンポーネントとグラフィック: 最低 3:1
3. セマンティクスのない HTML
❌ 問題:
<div class="button" onclick="submitForm()">Submit</div>
<div class="heading">Page Title</div>
<div class="nav-menu">...</div>
✅ 解決策:
<button type="submit" onclick="submitForm()">Submit</button>
<h1>Page Title</h1>
<nav aria-label="Main navigation">...</nav>
セマンティック要素:
- ボタンには
<button> - リンクには
<a> - 見出し(階層構造)には
<h1>〜<h6> - ランドマークには
<nav>、<main>、<aside>、<article>、<section> - リストには
<ul>、<ol>、<li> - 表形式のデータには
<table>、<th>、<td>
4. フォームラベルの欠落
❌ 問題:
<input type="email" placeholder="Enter your email">
✅ 解決策:
<label for="email">Email Address</label>
<input type="email" id="email" name="email">
<label>
Email Address
<input type="email" name="email">
</label>
<label for="search" class="sr-only">Search</label>
<input type="text" id="search" placeholder="Search...">
ベストプラクティス:
- すべてのフォームフィールドには、関連付けられたラベルが必要です
- ラベルは表示されている必要があります(プレースホルダーに頼らないでください)
- 視覚的なラベルが不可能な場合にのみ aria-label を使用してください
- 関連するフィールドは
<fieldset>と<legend>でグループ化してください
5. キーボードナビゲーションの問題
❌ 問題:
<div onclick="handleClick()">Click me</div>
<a href="javascript:void(0)" onclick="doSomething()">Action</a>
✅ 解決策:
<button onclick="handleClick()">Click me</button>
<div
role="button"
tabindex="0"
onclick="handleClick()"
onkeydown="handleKeyPress(event)"
>
Click me
</div>
<script>
function handleKeyPress(event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
handleClick();
}
}
</script>
キーボードの要件:
- すべての対話的要素はキーボードで操作可能である必要があります
- フォーカスインジケーターを視覚的に表示してください(アウトラインまたはカスタムスタイル)
- タブ順序は視覚的な流れに沿った論理的なものにしてください
- 繰り返し表示されるコンテンツには、スキップリンクを設けてください
- キーボードトラップを作らないでください(ユーザーが他の場所へ移動できること)
6. ARIA ランドマークの欠落
❌ 問題:
<div class="header">...</div>
<div class="main-content">...</div>
<div class="sidebar">...</div>
<div class="footer">...</div>
✅ 解決策:
<header role="banner">
<nav aria-label="Main navigation">...</nav>
</header>
<main role="main">
<h1>Page Title</h1>
<article>...</article>
</main>
<aside role="complementary" aria-label="Related articles">
...
</aside>
<footer role="contentinfo">
...
</footer>
一般的なランドマーク:
banner- サイトのヘッダーnavigation- ナビゲーションメニューmain- 主要コンテンツ(ページごとに 1 つ)complementary- 補足コンテンツcontentinfo- サイトのフッターsearch- 検索機能form- フォームの領域
7. アクセシブルでないモーダル/ダイアログ
❌ 問題:
<div class="modal">
<div class="content">
Modal content
<button onclick="closeModal()">Close</button>
</div>
</div>
✅ 解決策:
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-desc"
>
<h2 id="modal-title">Confirm Action</h2>
<p id="modal-desc">Are you sure you want to delete this item?</p>
<button onclick="confirmAction()">Confirm</button>
<button onclick="closeModal()">Cancel</button>
</div>
<script>
// Focus management
function openModal() {
const modal = document.querySelector('[role="dialog"]');
const focusableElements = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
// Store previous focus
previousFocus = document.activeElement;
// Focus first element
focusableElements[0].focus();
// Trap focus
modal.addEventListener('keydown', trapFocus);
}
function closeModal() {
// Return focus
if (previousFocus) previousFocus.focus();
}
function trapFocus(event) {
if (event.key !== 'Tab') return;
const focusableElements = Array.from(
modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (event.shiftKey && document.activeElement === firstElement) {
lastElement.focus();
event.preventDefault();
} else if (!event.shiftKey && document.activeElement === lastElement) {
firstElement.focus();
event.preventDefault();
}
}
</script>
モーダルの要件:
role="dialog"またはrole="alertdialog"- モーダルとして動作することを示す
aria-modal="true" - タイトルを指す
aria-labelledby - 説明用の
aria-describedby(任意) - フォーカス管理(閉じ込めと復元)
- Escape キーで閉じる
- 背景のスクロールを防止する
8. スキップリンクの欠落
✅ 解決策:
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<header>
<nav>...</nav>
</header>
<main id="main-content" tabindex="-1">
</main>
<style>
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
</style>
ARIA のベストプラクティス
ARIA 属性リファレンス
状態:
aria-checked- チェックボックス/ラジオボタンの状態aria-disabled- 無効状態aria-expanded- 展開/折りたたみの状態aria-hidden- 支援技術から非表示aria-pressed- トグルボタンの状態aria-selected- 選択状態
プロパティ:
aria-label- アクセシブルな名前aria-labelledby- ラベルの ID 参照aria-describedby- 説明の ID 参照aria-live- ライブリージョンの更新aria-required- 必須フィールドaria-invalid- 検証状態
ライブリージョン
<div aria-live="polite" aria-atomic="true">
Item added to cart
</div>
<div aria-live="assertive" role="alert">
Error: Payment failed
</div>
<div role="status" aria-live="polite">
Saving changes...
</div>
カスタムコンポーネント
アコーディオン:
<div class="accordion">
<button
aria-expanded="false"
aria-controls="panel-1"
id="accordion-1"
>
Section 1
</button>
<div id="panel-1" role="region" aria-labelledby="accordion-1" hidden>
Panel content
</div>
</div>
タブ:
<div role="tablist" aria-label="Content sections">
<button
role="tab"
aria-selected="true"
aria-controls="panel-1"
id="tab-1"
>
Tab 1
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-2"
id="tab-2"
tabindex="-1"
>
Tab 2
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
Panel 1 content
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
Panel 2 content
</div>
テストチェックリスト
自動テスト
- axe DevTools または WAVE ブラウザ拡張機能を実行する
- HTML の検証を行う(W3C Validator)
- 色のコントラスト比をテストする
- 見出しの階層構造を確認する
- 代替テキストの欠落がないか確認する
手動テスト
- キーボードのみ(Tab、Enter、Escape、矢印キー)でサイト全体を操作する
- スクリーンリーダー(NVDA、JAWS、VoiceOver)でテストする
- フォーカスインジケーターが表示されていることを確認する
- フォームの検証メッセージが読み上げられることを確認する
- モーダルのフォーカストラップをテストする
- スキップリンクが機能することを確認する
- ブラウザのズームを 200% にしてテストする
- さまざまなビューポートサイズでページのリフローを確認する
- JavaScript を無効にして、基本機能が動作することを確認する
- Windows ハイコントラストモードでテストする
スクリーンリーダーテスト
VoiceOver(Mac):
- 有効化: Cmd + F5
- 移動: Control + Option + 矢印キー
- すべて読み上げ: Control + Option + A
NVDA(Windows):
- 移動: 矢印キー(ブラウズモード)または Tab(フォーカスモード)
- すべて読み上げ: NVDA + 下矢印キー
- 要素リスト: NVDA + F7
テストシナリオ:
- ユーザーはページの構造を理解できるか?
- 見出しは内容を適切に示し、階層化されているか?
- フォームのラベルは明確で、入力欄に正しく関連付けられているか?
- エラーメッセージは読み上げられるか?
- ユーザーは視覚に頼らず主要なタスクを完了できるか?
アクセシビリティ声明
ウェブサイトに以下を掲載してください:
# Accessibility Statement
We are committed to ensuring digital accessibility for people with disabilities. We continually improve the user experience for everyone and apply relevant accessibility standards.
## Conformance Status
This website is partially conformant with WCAG 2.1 Level AA. "Partially conformant" means that some parts of the content do not fully conform to the accessibility standard.
## Feedback
We welcome your feedback on the accessibility of this site. Please contact us:
- Email: [email protected]
- Phone: +1-555-0123
## Known Issues
- [List any known accessibility issues and planned fixes]
Last updated: [Date]
リソース
ツール:
- axe DevTools(ブラウザ拡張機能)
- WAVE(Web アクセシビリティ評価ツール)
- Lighthouse(Chrome DevTools)
- Colour Contrast Analyser
- スクリーンリーダー: NVDA、JAWS、VoiceOver
ガイドライン:
- WCAG 2.1: https://www.w3.org/WAI/WCAG21/quickref/
- ARIA Authoring Practices: https://www.w3.org/WAI/ARIA/apg/
アクセシビリティは任意ではなく、インクルーシブなウェブ体験を作るための基本的な要件です。個々のプロジェクトの初期段階から優先的に取り組み、後回しにしないでください。
コメント
Markdown 対応