概要
アクセシビリティとは、“補助”ではなく“前提”である。
視覚・聴覚・運動・認知などの差異に配慮したUI設計は、**すべてのユーザーの操作体験を保証するための「構造的配慮」である。
JavaScriptを使ったインタラクションやSPA開発においても、“意味の伝達”“操作の再現”“構造の明示”**は設計の一部でなければならない。
本稿では、ARIA活用・キーボードナビゲーション・フォーカス管理・ライブリージョン・セマンティクス拡張を通して、アクセシブルなUI構造の設計戦略を解説する。
1. セマンティックHTMLの優先原則
<!-- ❌ divベースの非意味構造 -->
<div class="button" onclick="submit()">送信</div>
<!-- ✅ 意味のある構造 -->
<button type="submit">送信</button>
- ✅ スクリーンリーダーに「意味」を伝えるのは構造
- ✅ role="button" を指定する前に、“buttonを使えるか?”を常に自問
2. ARIA属性の基本と責任ある利用
✅ ARIAとは「Accessible Rich Internet Applications」
<div role="alert">パスワードが間違っています</div>
-
role="alert"
→ 自動読み上げ対象 -
aria-label
→ ラベルを上書き -
aria-hidden="true"
→ 読み上げから除外
→ ✅ ARIAは**「意味を補うもの」であり、「代替」ではない**
3. キーボードナビゲーションと操作保証
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
element.click();
}
});
- ✅
tabindex="0"
によりフォーカス可能に - ✅ Enter/Space による操作を模倣
- ✅
:focus-visible
を使ってフォーカスリング表示も制御
4. フォーカス管理の構造戦略
✅ ダイアログ表示時にフォーカスを制御
dialog.showModal();
dialog.querySelector('[autofocus]').focus();
- ✅ フォーカストラップで閉じるまで内部に留める
- ✅ 閉じたら元の要素にフォーカスを戻す
→ ✅ UIの状態遷移とフォーカスの整合性を保証
5. ライブリージョンと動的更新の読み上げ
<div role="status" aria-live="polite" id="statusMsg"></div>
document.getElementById('statusMsg').textContent = '保存されました';
- ✅
aria-live="polite"
→ 状況に応じて読み上げ - ✅
aria-live="assertive"
→ 即時読み上げ(エラーなど)
→ ✅ JavaScriptで内容を書き換えるだけでは読まれないことに注意
6. スクリーンリーダーと構造テスト戦略
- VoiceOver / NVDA / TalkBack などで実際に確認
-
aria-label
/aria-labelledby
の読み上げ整合性を検証 - Chrome DevTools > Accessibility パネルで構造確認
設計判断フロー
① この要素は意味があるか? → ネイティブ要素を使う
② 視覚以外の手段で意味が伝わるか? → ARIAで補完
③ キーボードで完全に操作可能か? → TabIndex + KeyEvent を設計
④ 状態変化は伝わるか? → aria-live や role を活用
⑤ JavaScriptで制御して壊していないか? → フォーカス制御を設計に織り込む
よくあるミスと対策
❌ divを使って「ボタンのような見た目」だけにする
→ ✅ 意味的には<button>
を使用する方が遥かに安全・汎用的
❌ JavaScriptでテキストを変更しても読み上げられない
→ ✅ aria-live
属性で読み上げのトリガー構造を用意
❌ ダイアログを開いたが、フォーカスが前の画面に残る
→ ✅ focus()
を手動制御 + トラップ設計を導入
結語
アクセシビリティとは、“余裕があればやる”ことではない。
それは、“最初から設計に含めておくべき構造的責任”である。
- 要素は意味を持ち
- 状態は伝わり
- 操作はすべての人に届くように設計されるべきだ
アクセシビリティ設計とは、
“全てのユーザーの尊厳をコードに込める”ための技術的表現である。