mcpField
W
wcag-audit-patterns

wcag-audit-patterns

github.com/marcioaltoeテスト・品質046 回インストール1 日前に更新
リポジトリ

wcag-audit-patterns について

WCAG 2.2 に基づいてウェブコンテンツを監査し、修正を計画するためのリファレンススキルです。開発者やアクセシビリティのレビュー担当者向けに、チェックリスト、コード例、自動テストの指針を提供します。

主な機能

  1. 01WCAG 適合レベルと POUR 原則
  2. 02アクセシビリティ基準別の監査チェックリスト
  3. 03よくある問題と修正パターン
  4. 04axe-core と Playwright のテスト例
  5. 05アクセシビリティ検査コマンドの例

活用シーン

  1. 01ウェブサイトの WCAG 問題の確認
  2. 02フォームラベルやキーボード操作の修正計画
  3. 03Playwright テストへのアクセシビリティ検査追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/marcioaltoe/skills --skill wcag-audit-patterns

インストール後、Claude Code で/wcag-audit-patternsを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yaml

詳細

WCAG 監査パターン

WCAG 2.2 ガイドラインに照らしてウェブコンテンツを監査し、実行可能な修正方法を示す包括的なガイドです。

このスキルを使用する場面

  • アクセシビリティ監査を実施する
  • WCAG 違反を修正する
  • アクセシブルなコンポーネントを実装する
  • アクセシビリティ関連の訴訟に備える
  • ADA/Section 508 の要件を満たす
  • VPAT 準拠を達成する

主な概念

1. WCAG 適合レベル
レベル説明必要とされる対象
A最低限のアクセシビリティ法的な最低基準
AA標準的な適合性ほとんどの規制
AAA高度なアクセシビリティ特殊なニーズ
2. POUR の原則
Perceivable:  Can users perceive the content?
Operable:     Can users operate the interface?
Understandable: Can users understand the content?
Robust:       Does it work with assistive tech?
3. 影響度別のよくある違反
Critical (Blockers):
├── Missing alt text for functional images
├── No keyboard access to interactive elements
├── Missing form labels
└── Auto-playing media without controls

Serious:
├── Insufficient color contrast
├── Missing skip links
├── Inaccessible custom widgets
└── Missing page titles

Moderate:
├── Missing language attribute
├── Unclear link text
├── Missing landmarks
└── Improper heading hierarchy

監査チェックリスト

知覚可能(原則 1)
## 1.1 Text Alternatives

### 1.1.1 Non-text Content (Level A)

- [ ] All images have alt text
- [ ] Decorative images have alt=""
- [ ] Complex images have long descriptions
- [ ] Icons with meaning have accessible names
- [ ] CAPTCHAs have alternatives

Check:

```html

<img src="chart.png" alt="Sales increased 25% from Q1 to Q2" />
<img src="decorative-line.png" alt="" />


<img src="chart.png" />
<img src="decorative-line.png" alt="decorative line" />
```

1.2 時間依存メディア

1.2.1 音声のみおよび映像のみ(レベル A)
  • 音声にテキストの書き起こしがある
  • 映像に音声解説または書き起こしがある
1.2.2 キャプション(レベル A)
  • すべての映像に同期したキャプションがある
  • キャプションが正確で完全である
  • 話者の識別情報が含まれている
1.2.3 音声解説(レベル A)
  • 映像に視覚的なコンテンツの音声解説がある

1.3 適応可能

1.3.1 情報と関係性(レベル A)
  • 見出しに適切なタグ(h1-h6)を使用している
  • リストに ul/ol/dl を使用している
  • テーブルに見出しがある
  • フォームの入力欄にラベルがある
  • ARIA ランドマークがある

確認項目:


<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h2>Another Section</h2>


<table>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Price</th>
    </tr>
  </thead>
</table>
1.3.2 意味のある順序(レベル A)
  • 読み上げ順序が論理的である
  • CSS による配置で順序が崩れていない
  • フォーカス順序が視覚的な順序と一致している
1.3.3 感覚的な特徴(レベル A)
  • 指示が形や色だけに依存していない
  • 「赤いボタンをクリック」→「送信(赤いボタン)をクリック」

1.4 識別可能

1.4.1 色の使用(レベル A)
  • 情報を伝える手段が色だけではない
  • リンクが色以外の方法でも識別できる
  • エラー状態が色だけで示されていない

ツール:WebAIM Contrast Checker、axe DevTools

1.4.3 コントラスト(最低限)(レベル AA)
  • テキスト:コントラスト比 4.5:1
  • 大きなテキスト(18pt 以上):比率 3:1
  • UI コンポーネント:比率 3:1
1.4.4 テキストのサイズ変更(レベル AA)
  • 情報を失わずにテキストを 200% まで拡大できる
  • 幅 320px で横スクロールが発生しない
  • コンテンツが適切にリフローする
1.4.10 リフロー(レベル AA)
  • 400% ズームでコンテンツがリフローする
  • 2 次元スクロールが発生しない
  • 幅 320px ですべてのコンテンツにアクセスできる
1.4.11 非テキストのコントラスト(レベル AA)
  • UI コンポーネントのコントラスト比が 3:1 である
  • フォーカスインジケーターが見える
  • グラフィックオブジェクトを識別できる
1.4.12 テキスト間隔(レベル AA)
  • 間隔を広げてもコンテンツが失われない
  • 行の高さがフォントサイズの 1.5 倍である
  • 段落の間隔がフォントサイズの 2 倍である
  • 文字間隔がフォントサイズの 0.12 倍である
  • 単語間隔がフォントサイズの 0.16 倍である

### Operable (Principle 2)

```markdown
## 2.1 Keyboard Accessible

### 2.1.1 Keyboard (Level A)
- [ ] All functionality keyboard accessible
- [ ] No keyboard traps
- [ ] Tab order is logical
- [ ] Custom widgets are keyboard operable

Check:
```javascript
// Custom button must be keyboard accessible
<div role="button" tabindex="0"
     onkeydown="if(event.key === 'Enter' || event.key === ' ') activate()">
2.1.2 キーボードトラップなし(レベル A)
  • すべてのコンポーネントからフォーカスを移動できる
  • モーダルダイアログでフォーカスが適切にトラップされる
  • モーダルを閉じた後にフォーカスが戻る

2.2 十分な時間

2.2.1 時間調整可能(レベル A)
  • セッションのタイムアウトを延長できる
  • タイムアウト前にユーザーに警告する
  • 自動更新を無効にするオプションがある
2.2.2 一時停止、停止、非表示(レベル A)
  • 動きのあるコンテンツを一時停止できる
  • 自動更新するコンテンツを一時停止できる
  • アニメーションが prefers-reduced-motion を尊重する
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

2.3 発作および身体的反応

2.3.1 3 回の閃光(レベル A)
  • 1 秒間に 3 回を超えて点滅するコンテンツがない
  • 点滅する領域が小さい(ビューポートの 25% 未満)

2.4 ナビゲーション可能

2.4.1 ブロックの回避(レベル A)
  • メインコンテンツへのスキップリンクがある
  • ランドマーク領域が定義されている
  • 見出し構造が適切である
<a href="#main" class="skip-link">Skip to main content</a>
<main id="main">...</main>
2.4.2 ページタイトル(レベル A)
  • ページタイトルが一意で、内容を説明している
  • タイトルがページの内容を反映している
2.4.3 フォーカス順序(レベル A)
  • フォーカス順序が視覚的な順序と一致している
  • tabindex が正しく使用されている
2.4.4 リンクの目的(文脈内)(レベル A)
  • リンクは文脈から切り離しても意味が通じる
  • 「ここをクリック」や「続きを読む」だけのリンクにしない

<a href="report.pdf">Click here</a>


<a href="report.pdf">Download Q4 Sales Report (PDF)</a>
2.4.6 見出しとラベル(レベル AA)
  • 見出しは内容を説明している
  • ラベルは目的を説明している
2.4.7 フォーカスの可視化(レベル AA)
  • すべての要素でフォーカスインジケーターが見える
  • カスタムフォーカススタイルがコントラスト要件を満たしている
:focus {
  outline: 3px solid #005fcc;
  outline-offset: 2px;
}
2.4.11 フォーカスを隠さない(レベル AA)- WCAG 2.2
  • フォーカス中の要素が完全に隠れない
  • 固定ヘッダーがフォーカスを隠さない

### Understandable (Principle 3)

```markdown
## 3.1 Readable

### 3.1.1 Language of Page (Level A)
- [ ] HTML lang attribute set
- [ ] Language correct for content

```html
<html lang="en">
3.1.2 部分的な言語の指定(レベル AA)
  • 言語の変更がマークされている
<p>The French word <span lang="fr">bonjour</span> means hello.</p>

3.2 予測可能

3.2.1 フォーカス時(レベル A)
  • フォーカスだけでコンテキストが変わらない
  • フォーカス時に予期しないポップアップが表示されない
3.2.2 入力時(レベル A)
  • フォームが自動送信されない
  • コンテキストの変更前にユーザーに警告する
3.2.3 一貫したナビゲーション(レベル AA)
  • ページ間でナビゲーションが一貫している
  • 繰り返し使用するコンポーネントの順序が同じである
3.2.4 一貫した識別(レベル AA)
  • 同じ機能には同じラベルを使用する
  • アイコンを一貫して使用する

3.3 入力支援

3.3.1 エラーの識別(レベル A)
  • エラーが明確に識別されている
  • エラーメッセージが問題を説明している
  • エラーがフィールドに関連付けられている
<input aria-describedby="email-error" aria-invalid="true" />
<span id="email-error" role="alert">Please enter valid email</span>
3.3.2 ラベルまたは説明(レベル A)
  • すべての入力に表示されるラベルがある
  • 必須フィールドが示されている
  • 入力形式のヒントが示されている
3.3.3 エラーの修正案(レベル AA)
  • エラーに修正案が含まれている
  • 修正案が具体的である
3.3.4 エラーの防止(レベル AA)
  • 法的または金銭に関するフォームで、入力を取り消せる
  • 送信前にデータが確認される
  • 送信前にユーザーが内容を確認できる

### Robust (Principle 4)

```markdown
## 4.1 Compatible

### 4.1.1 Parsing (Level A) - Obsolete in WCAG 2.2
- [ ] Valid HTML (good practice)
- [ ] No duplicate IDs
- [ ] Complete start/end tags

### 4.1.2 Name, Role, Value (Level A)
- [ ] Custom widgets have accessible names
- [ ] ARIA roles correct
- [ ] State changes announced

```html

<div role="checkbox"
     aria-checked="false"
     tabindex="0"
     aria-labelledby="label">
</div>
<span id="label">Accept terms</span>
4.1.3 ステータスメッセージ(レベル AA)
  • ステータスの更新が通知される
  • ライブリージョンが正しく使用されている
<div role="status" aria-live="polite">3 items added to cart</div>

<div role="alert" aria-live="assertive">Error: Form submission failed</div>

## Automated Testing

```javascript
// axe-core integration
const axe = require('axe-core');

async function runAccessibilityAudit(page) {
  await page.addScriptTag({ path: require.resolve('axe-core') });

  const results = await page.evaluate(async () => {
    return await axe.run(document, {
      runOnly: {
        type: 'tag',
        values: ['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa']
      }
    });
  });

  return {
    violations: results.violations,
    passes: results.passes,
    incomplete: results.incomplete
  };
}

// Playwright test example
test('should have no accessibility violations', async ({ page }) => {
  await page.goto('/');
  const results = await runAccessibilityAudit(page);

  expect(results.violations).toHaveLength(0);
});
# CLI tools
npx @axe-core/cli https://example.com
npx pa11y https://example.com
lighthouse https://example.com --only-categories=accessibility

改善パターン

修正:フォームラベルがない

<input type="email" placeholder="Email" />


<label for="email">Email address</label>
<input id="email" type="email" />


<input type="email" aria-label="Email address" />


<span id="email-label">Email</span>
<input type="email" aria-labelledby="email-label" />
修正:色のコントラストが不十分
/* Before: 2.5:1 contrast */
.text {
  color: #767676;
}

/* After: 4.5:1 contrast */
.text {
  color: #595959;
}

/* Or add background */
.text {
  color: #767676;
  background: #000;
}
修正:キーボードナビゲーション
// Make custom element keyboard accessible
class AccessibleDropdown extends HTMLElement {
  connectedCallback() {
    this.setAttribute("tabindex", "0");
    this.setAttribute("role", "combobox");
    this.setAttribute("aria-expanded", "false");

    this.addEventListener("keydown", (e) => {
      switch (e.key) {
        case "Enter":
        case " ":
          this.toggle();
          e.preventDefault();
          break;
        case "Escape":
          this.close();
          break;
        case "ArrowDown":
          this.focusNext();
          e.preventDefault();
          break;
        case "ArrowUp":
          this.focusPrevious();
          e.preventDefault();
          break;
      }
    });
  }
}

ベストプラクティス

推奨事項
  • 早期に着手する - 設計段階からアクセシビリティに取り組みます
  • 実際のユーザーでテストする - 障害のあるユーザーから最も有益なフィードバックが得られます
  • 自動化できることは自動化する - 問題の30~50%は検出可能です
  • セマンティックHTMLを使用する - ARIAの必要性を減らせます
  • パターンを文書化する - アクセシブルなコンポーネントライブラリを構築します
避けるべきこと
  • 自動テストだけに頼らない - 手動テストも必要です
  • 最初の解決策としてARIAを使わない - まずネイティブHTMLを使用します
  • フォーカスのアウトラインを隠さない - キーボードを使うユーザーには必要です
  • ズームを無効にしない - ユーザーが表示サイズを変更できる必要があります
  • 色だけに頼らない - 複数の識別手段が必要です

コメント