概要
アクセシビリティとは「使いやすさ」ではない。
それは**「すべてのユーザーが、意味にたどり着けること」を保証する構造**である。
JavaScriptを用いて動的なUIを設計する時、
見た目が変わることよりも、構造と意味が伝わることが優先される。
本稿では、JavaScript実装におけるA11y設計戦略を、構造/操作/通知/意味の4つの観点から整理する。
1. キーボード操作の対応は最優先事項
✅ クリック操作と同等のキーボード操作を提供する
button.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
triggerAction();
}
});
- ✅
<button>
タグを使えば基本対応は不要(HTML標準で対応済) - ❌
div
やspan
にonclick
を付けると、キーボード非対応のUIが生まれる
2. フォーカス制御と tabindex
✅ 動的要素に tabindex
を明示的に設定
<div tabindex="0">Focusable</div>
- ✅ フォーカス順を明示
- ✅
tabindex="-1"
はスクリプトでのfocus()
用(ユーザー操作ではフォーカス不可)
3. ARIAロールと属性で意味を伝える
<div role="alert" aria-live="assertive">
エラーが発生しました。
</div>
- ✅
role="button"
やrole="dialog"
などで意味を付与 - ✅
aria-live
によって動的変化を読み上げ可能に
→ ✅ ARIA属性は“構造”ではなく“補完”として使うべき(semantic HTMLが第一)
4. ダイアログ・モーダル設計の責務
✅ 初期フォーカス + 閉じるボタンへのキーボード対応 + フォーカストラップ
modal.querySelector('button').focus(); // 初期フォーカス
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeModal();
});
- ✅ モーダル内のみ
Tab
移動可能に(フォーカストラップ) - ✅
aria-modal="true"
+role="dialog"
+aria-labelledby
5. 視覚支援・読み上げ対応の原則
- ✅ テキストは
aria-label
oraria-labelledby
で明示
<input type="search" aria-label="商品を検索">
- ✅
aria-describedby
で補足文の読み上げ指定 - ✅
aria-hidden="true"
で読み上げ対象外に(UI用アイコンなど)
6. A11y設計のチェックリスト
☑ すべての機能がキーボードで操作可能か?
☑ 意味のあるHTMLタグを使っているか?
☑ 視覚情報に頼らず意味が伝わるか?
☑ 状態変化がスクリーンリーダーに伝わっているか?
☑ 動的に追加された要素にもARIAが適用されているか?
よくあるミスと対策
❌ <div onclick="...">
でボタンを実装し、キーボード非対応に
→ ✅ <button>
要素を使用 or role="button"
+ tabindex="0"
+ keydown
実装
❌ 動的エラー表示が読み上げられない
→ ✅ aria-live
コンテナに出力し、スクリーンリーダーに変化を通知
❌ フォーカスがモーダル外に移動し、操作不能に
→ ✅ フォーカストラップ設計 + モーダル解除で元の要素に戻す
結語
アクセシビリティとは「配慮」ではない。
それは**“すべてのユーザーが到達できる構造を選ぶ”という設計上の責任**である。
- 見た目より構造を優先し
- 操作より意味を保証し
- 技術より設計を選ぶ
JavaScriptにおけるアクセシビリティ設計とは、
“誰もが使えることを、当たり前に保証する構造戦略”である。