Communitygithub.com

フロントエンドアクセシビリティ (Frontend Accessibility)

対話的なコンポーネント、フォーム、ダイアログ、ページの構築・保守時に使用します。セマンティックHTML優先、キーボード操作、コントラスト比、ラベル付き入力、動きの設定尊重など、WCAG 2.1 AAを適用します。モーダル追加、ドロップダウン作成、フォームバリデーション、キーボードナビゲーション、スクリーンリーダー、コントラスト、アクセシビリティ監査の際にトリガーされます。

フロントエンドアクセシビリティ (Frontend Accessibility) とは?

このスキルは、フロントエンドプロジェクトにおいてWCAG 2.1 Level AAへの準拠を強制するための包括的なルールセットです。「セマンティックHTMLファースト」の方針を基盤とし、`<button>`や`<a>`などの適切な要素を使用し、ARIAはHTMLでは対応できない場合にのみ補足的に利用します。キーボード操作は必須で、すべてのインタラクティブ要素にTabで到達でき、フォーカスは常に可視である必要があります。コントラスト比は通常テキストで4.5:1、大きなテキストで3:1を要求し、色だけで情報を伝えることを禁止します。フォームのラベル付け、エラーメッセージの紐付け、ターゲットサイズ(タッチ操作では44×44px推奨)、`prefers-reduced-motion`の尊重など、多岐にわたる細かなルールを含みます。また、自動テスト(Playwright + Axe)やスクリーンリーダーによる手動テストを開発作業の一部として組み込むことを求めています。参照実装はリポジトリ内の `references/component-patterns.md` にあり、ボタン、フォーム入力、ダイアログ、リストボックス、スキップリンクなどのパターンが提供されています。このスキールはプロジェクトコンベンションを`STACK-PROFILE.md`から解決し、既存の規約を尊重して新しい発明を避けることで、現実のプロジェクトにシームレスに統合できるよう設計されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/chandra-pangea/plugin-ax-ai-ts-full-stack/tree/HEAD/claude/skills/frontend-accessibility

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

フロントエンドアクセシビリティ

<ui-packages-dir> 内のコンポーネントと <web-dir>/src/ 内のページに適用されます。ターゲットは WCAG 2.1 Level AA であり、これは目標ではなく最低基準です。

プロジェクト規約の解決

山括弧内の値はプロジェクトのスタックプロファイルから取得します。次の順序で解決します:

  1. リポジトリルートにある STACK-PROFILE.md を読み、その値をそのまま使用します。
  2. ファイルがないかキーが欠けている場合は、リポジトリから推測します — css-strategy と ui-framework はWebアプリケーションの依存関係から取得します。
  3. それでも解決できない場合は、リポジトリ内ですでに支配的な規約に合わせます。
  4. リポジトリが空の場合のみ、このスキルに規定されたデフォルトにフォールバックします — その後、選択した値を STACK-PROFILE.md に書き込みます。

リポジトリがすでに規約を表現している場合、新しい規約を発明してはいけません。


厳格なルール

1. セマンティックHTMLファースト

  • アクションには <button>、ナビゲーションには <a> を使用します。クリックハンドラを持つ <div> は禁止です。
  • 見出しレベルはスキップせずに降順で使用します。
  • すべてのフォームフィールドに <label> を付け、htmlFor で関連付けます。
  • グループ化されたコントロールには <fieldset> と <legend> を使用します。
  • ランドマーク — <nav>、<main>、<footer>、<aside> — をすべてのページに配置します。

2. ARIAはHTMLでできない場合のみ

優先順位はセマンティック要素、次にARIA属性、最後にカスタム動作です。要素がすでに持つセマンティクスを上書きするためにARIAを使用してはいけません — <div> に role="button" を付けるのは、<button> が無料で提供するものを拙劣に再実装するだけです。

誤ったARIAはないより悪いです: 間違った aria-label は、スクリーンリーダーが本来正しく計算するアクセシブルな名前を静かに置き換えてしまいます。

3. キーボード操作は必須

  • すべてのインタラクティブな要素がTabキーで到達可能であること。
  • Tab順序は視覚的な順序に従うこと。
  • フォーカスは常に可視であること。アウトラインを削除する場合は必ず代替を設定すること。
  • Escape でダイアログとポップオーバーを閉じ、Enter と Space でコントロールをアクティブにし、矢印キーで複合ウィジェット内を移動します。
  • カスタムウィジェットは明示的にフォーカスを管理します。

4. 色とコントラスト

  • 通常テキストは4.5:1、大きなテキスト(18px、または14pxの太字)および意味のあるUI境界線は3:1。
  • 色だけに意味を持たせてはいけません — テキスト、アイコン、またはパターンと組み合わせます。
  • デフォルトのテーマだけでなく、両方のテーマをチェックします。

5. 画像とメディア

  • すべての画像に alt 属性を付けます。コンテンツ画像は説明的に、装飾画像は alt="" とします。
  • 「画像」「写真」、またはファイル名をaltテキストに使ってはいけません。
  • 複雑な画像には、aria-describedby またはキャプションを通じて長い説明を提供します。
  • 動画にはキャプション、音声にはトランスクリプトを付けます。

6. フォーム

  • すべての入力にラベルを付けます。
  • エラーは aria-describedby でリンクし、role="alert" でアナウンスします。
  • 無効なフィールドには aria-invalid をマークします。
  • 必須フィールドには required 属性を付けます — アスタリスクを表示する場合、その意味はどこかにテキストで記載します。
  • 送信失敗時は、最初の無効なフィールドにフォーカスを移動します。

7. ターゲットサイズ

WCAG 2.1 AA には最小ターゲットサイズはありません(2.2 AA では24×24 CSS pxを設定; 44×44は2.1 AAAおよびプラットフォームHIGの慣例です)。タッチサーフェス上のプライマリアクションでは44×44を下限として扱い、次のように適用します:

  • プライマリおよびデストラクティブなアクション、およびユーザーが電話で触れるもの: 44×44。
  • 高密度なデスクトップクローム — ツールバー、テーブル行アクション、コンパクトなフォームコントロール — は、ターゲットが他のターゲットに隣接しておらず、同等のフルサイズのコントロールが別の場所に存在する場合、24×24まで小さくしても構いません。
  • 間隔も重要です。32pxのコントロールでも、各側に6pxの明確なスペースがあれば2.2の基準を満たしますが、隣接するコントロールに接触している32pxのコントロールは満たしません。

ベンダー製コンポーネントライブラリは通常この下限を下回って出荷されます — デフォルトのボタンの高さが32または36 CSS pxであることは一般的です。ベンダーファイルを手動で編集して修正してはいけません。また、デフォルトで不一致を受け入れてはいけません。<wrappers-pkg> でデフォルトを引き上げ、すべてのコンシューマーが準拠したサイズを継承するようにし、小さなサイズは高密度なコンテキスト用の明示的なオプトインとして利用できるようにします。そうすることで、アクセシブルな選択肢が、考えずに使用した場合のデフォルトになります。

プロジェクトがどの解決策を採用したかを STACK-PROFILE.md に記録します。表明されていない例外は、半年ごとにバグとして再発見されます。

8. モーション

  • prefers-reduced-motion を尊重します。
  • 自動再生コンテンツには一時停止コントロールが必要です。
  • 毎秒3回以上の点滅は禁止です。

9. テストは作業の一部

  • キーボードだけで機能を操作します。
  • スクリーンリーダーで聞きます — macOSではVoiceOver、WindowsではNVDA。
  • エンドツーエンドスイートで自動スキャンを実行します。

自動化ツールは実際の問題の約3分の1を検出します。これらは合格基準ではなく、下限です。


パターン

完全な実装は references/component-patterns.md にあります。各パターンが保証する内容:

  • ボタン — セマンティックな <button> で、フォーカスリングがキーボードユーザーには表示されるがマウスクリックでは表示されない(focus-visible)、モーションセーフなトランジション、アイコンのみの使用には ariaLabel プロパティ。
  • フォーム入力 — ラベル付き入力で、エラーテキストが aria-describedby でプログラム的にリンクされ、role="alert" でアナウンスされ、aria-invalid でフラグが立てられる; 必須アスタリスクは aria-hidden。
  • ダイアログ — ネイティブの <dialog> を使用し、showModal() で無料のフォーカストラップ、Escape 処理、およびバックグラウンドの inert を実現; 開くときにフォーカスが移動し、閉じるとトリガーに戻る。
  • リストボックス — カスタムセレクトで、矢印キーによる巡回ナビゲーションと正しいARIA配線(aria-activedescendant、role="listbox"); ネイティブの <select> が適さない場合のみ構築する。
  • スキップリンク — キーボードユーザーがナビゲーションをスキップできるようにし、フォーカスされたときのみ表示; ターゲットは tabIndex={-1} を持ち、フォーカスが実際にそこに移動する。

WCAG クイックリファレンス

原則要件実際の対応
知覚可能コンテンツがすべての感覚で利用可能Altテキスト、キャプション、色+アイコン
操作可能すべてがキーボードで到達可能Tab順序、Escapeで閉じる、フォーカス可視
理解可能予測可能、明確な表現一貫したナビゲーション、平易な言語
堅牢支援技術と連携有効なHTML、正しいARIA、セマンティック要素
問題修正
ラベルなし入力<label htmlFor> を追加
低コントラスト通常テキスト4.5:1、大きなテキスト3:1を満たす
キーボード経路なし実際のインタラクティブ要素、フォーカス管理
alt欠落説明する、または装飾の場合は alt=""
色のみの意味テキストまたはアイコンを追加
アイコンのみのボタンaria-label を追加
点滅コンテンツ毎秒3回未満に抑える

モーション設定

プレーンなCSSで縮小モーションを処理します。motion-safe: のようなユーティリティクラスバリアントは、モーションが許可されている場合にのみ適用されるため、縮小モーションクエリ内に配置すると、決してマッチしないルールになります。

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

ゼロに近い値(noneではない)にすることで、トランジション終了イベントが発生し続け、それを待つコンポーネントがハングしません。

コンポーネントごとの制御には、アニメーションユーティリティ自体に motion-safe: バリアントを適用します — 上記のボタンのように motion-safe:transition-colors のようにします。

視覚的に隠されたコンテンツ

ほとんどのユーティリティフレームワークはすでに sr-only と not-sr-only を提供しています。それらを使用し、再定義しないでください。提供されていない場合、参照実装は references/component-patterns.md にあります。


テストチェックリスト

キーボード

  • すべてのインタラクティブ要素がTabで到達可能
  • Tab順序が視覚的な順序と一致
  • フォーカスが常に可視
  • Escapeでダイアログとポップオーバーを閉じる
  • 矢印キーが複合ウィジェットで機能する
  • ダイアログが閉じるとフォーカスがトリガーに戻る

スクリーンリーダー

  • すべてのコンテンツに到達可能
  • コントロールの目的が周囲のコンテキストなしで明確
  • ラベルがフィールドとともにアナウンスされる
  • エラーが role="alert" を通じてアナウンスされる
  • ランドマークが存在する
  • 装飾要素が aria-hidden で隠されている

色

  • 通常テキスト4.5:1、大きなテキストとUI境界線3:1
  • 色のみの意味なし
  • 両方のテーマを確認

モーション

  • 縮小モーションが尊重されている
  • 毎秒3回以上の点滅なし
  • 自動再生コンテンツが一時停止可能

自動化

スキャンはPlaywrightスイート内で実行されます — frontend-testing を参照。Playwright内のAxeスニペットは references/component-patterns.md にあります。

参照ドキュメント

詳細参照
アクセシブルコンポーネント実装: ボタン、フォーム入力、モーダル、リストボックス、スキップリンクreferences/component-patterns.md

関連スキル

  • frontend-architecture — コンポーネントの階層とテーマ設定
  • frontend-testing — これらのチェックが実行される場所
  • frontend-component-docs — コンポーネントのアクセシビリティ契約の文書化

関連スキル