概要
DOM操作はUIを構築する力であると同時に、アクセシビリティ(a11y)を破壊する力でもある。
見た目だけでなく、構造的意味・操作性・ナビゲーション可能性を保ったままDOMを動的に変更することが、モダンなJavaScript UI設計には求められる。
本稿では以下の観点で整理する:
- 意味論的HTMLとDOM操作の整合
- aria属性の設計と状態管理
- フォーカス管理とキーボードナビゲーション
- UI状態とDOM属性の同期
- ライブリージョンによる動的通知
1. 意味論的HTML(semantic HTML)との協調
❌ div
ベースの構造操作
const el = document.createElement('div');
el.innerText = 'Click me';
el.addEventListener('click', handleClick);
→ 非セマンティック、スクリーンリーダー未対応
✅ HTML5タグ + 明示的な属性
const button = document.createElement('button');
button.innerText = '削除';
button.setAttribute('aria-label', 'この項目を削除');
- ✅
button
,nav
,section
,dialog
などのHTMLタグを優先 - ✅ アクション要素は
role="button"
ではなく<button>
で
2. aria属性と状態同期
const menu = document.getElementById('menu');
menu.setAttribute('aria-expanded', 'false');
function toggleMenu() {
const expanded = menu.getAttribute('aria-expanded') === 'true';
menu.setAttribute('aria-expanded', String(!expanded));
}
- ✅ 状態変更時に
aria-*
を明示的に同期 - ✅
aria-expanded
,aria-hidden
,aria-pressed
など状態を語る属性を積極的に使う
3. フォーカス管理:動的要素とアクセシビリティの両立
const modal = document.getElementById('dialog');
modal.showModal();
modal.querySelector('button.close').focus(); // フォーカスを送る
- ✅ ダイアログ表示時は初期フォーカスを明示的に設定
- ✅
tabindex="-1"
を使ってJSからフォーカス可能にするのが定石
4. キーボードナビゲーション設計
element.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closeDialog();
}
});
- ✅ Escape → ダイアログ閉じる
- ✅ Enter/Space → ボタンを発火
- ✅ 矢印キー → リストナビゲーション etc.
→ キーボード操作が全UIと等価であることが重要
5. aria-live:動的更新の通知
<div id="announce" aria-live="polite" class="sr-only"></div>
announce.textContent = '保存に成功しました';
- ✅ ユーザーに見えないがスクリーンリーダーには通知される
- ✅
aria-live="polite"
(非強制) /assertive
(即時)
6. UI状態とDOM構造の同期責任
function toggleSection(section, isOpen) {
section.setAttribute('aria-hidden', String(!isOpen));
section.classList.toggle('hidden', !isOpen);
}
→ ✅ 視覚的状態(class)と意味的状態(aria)を同期させる
7. モジュールとしての責任分離
-
dom/createButton.js
→ ボタン生成 -
a11y/setAriaExpanded.js
→ ARIA属性の更新 -
focus/trapFocus.js
→ モーダル内でのタブ移動制御
→ ✅ 各ファイルが1つの意味的責務を担い、明示的な設計となる
設計判断フロー
① 操作対象は何か? → ボタン・入力など意味のあるHTMLタグを使う
② 状態がある? → aria属性で状態を表現(expanded, pressed)
③ 動的UI? → DOM更新に合わせてARIAやフォーカスも更新
④ 通知が必要? → aria-liveで視覚外の情報を伝える
⑤ キーボード操作に対応しているか? → keydown/keyupで補完
よくあるミスと対策
❌ <div>
をボタン代わりにクリックイベント
→ ✅ button
タグで、アクセシビリティと自動フォーカスを確保
❌ 状態だけclassで制御、aria未設定
→ ✅ classとariaを並行管理する
❌ ダイアログやモーダルにフォーカスが移らない
→ ✅ focus()
と tabindex="-1"
を組み合わせて制御
結語
DOM操作とは、UIの見た目を変える技術ではない。
それはユーザーがどう見るか、どう理解するか、どう操作するかを構造として設計する技術である。
- 意味を持つHTMLを選び
- 状態を属性で語り
- 操作をキーボードと同期し
- 表示されない情報も伝える
アクセシブルなDOM操作は、すべてのユーザーに届く設計である。
その設計は、構文・視覚・操作性の三位一体で成立する。