- Modalを開くユーティリティは「ユーザーの集中を一時的に一点に集めるための仕組み」です
- ステップ1:Modalの基本構造を理解する
- ステップ2:CSSで「開いている状態」と「閉じている状態」を切り替えられるようにする
- ステップ3:Modalを開く・閉じるための基本ユーティリティ
- ステップ4:ボタンとModalを紐づける(イベントハンドラ)
- ステップ5:業務でよくある「確認Modal」のテンプレート
- ステップ6:アクセシビリティ(キーボード操作・フォーカス制御)への配慮(重要な深掘り)
- ステップ7:複数Modalを扱うときの設計(シンプルさを保つ)
- ステップ8:絶対に避けるべき危険な・使いづらいパターンを明確にしておく
- ステップ9:チームで共有するための「Modal設計ルール」をコードとドキュメントに刻む
- まとめ:Modalを開くユーティリティは「ユーザーの集中を一時的に一点に集めるための、実務的で欠かせないUI技術」です
Modalを開くユーティリティは「ユーザーの集中を一時的に一点に集めるための仕組み」です
業務システムやWebアプリケーションでは、Modal(モーダルダイアログ)は非常によく使われます。
- 確認ダイアログ(削除確認、送信確認など)
- 詳細情報の表示(レコードの詳細、ヘルプテキストなど)
- フォーム入力(小さな編集フォーム、設定変更など)
Modalは「画面の上に重ねて表示される小さなウィンドウ」であり、 ユーザーの視線と操作を一時的にそこへ集中させるためのUI部品です。
ここでは、初心者向けに、
- Modalの基本構造
- JavaScriptでModalを開く・閉じるユーティリティ
- 業務で使いやすい設計と注意点
をステップバイステップで解説していきます。
ステップ1:Modalの基本構造を理解する
まず、ModalがどのようなHTML構造でできているかを押さえます。
典型的なModalのHTML構造
<div class="modal-backdrop" id="my-modal" aria-hidden="true">
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">タイトル</h2>
<button class="modal-close" type="button" aria-label="閉じる">×</button>
</div>
<div class="modal-body">
ここに内容が入ります。
</div>
<div class="modal-footer">
<button type="button" class="modal-cancel">キャンセル</button>
<button type="button" class="modal-ok">OK</button>
</div>
</div>
</div>
ここで重要なのは次の点です。
modal-backdrop:画面全体を覆う半透明の背景(クリックを遮る役割もあります)modal:中央に表示されるダイアログ本体- ヘッダー・ボディ・フッター:タイトル、内容、ボタンなどを配置する領域
CSS側では、
- 初期状態では非表示(
display: noneやopacity: 0) - Modalを開くときにクラスを付け替えて表示する
というスタイルにしておくことが多いです。
ステップ2:CSSで「開いている状態」と「閉じている状態」を切り替えられるようにする
JavaScriptでModalを開くためには、 CSS側で「開いている状態」と「閉じている状態」を切り替えられるようにしておく必要があります。
例:CSSの基本
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.4);
display: none; /* 初期状態は非表示 */
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-backdrop.is-open {
display: flex; /* 開いているときは中央寄せで表示 */
}
.modal {
background: #fff;
border-radius: 4px;
padding: 16px;
max-width: 480px;
width: 100%;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
ここでは、
.modal-backdropにdisplay: noneを設定して非表示にしておき、.modal-backdrop.is-openのときだけdisplay: flexで表示する
というシンプルな切り替えをしています。
ポイント:JavaScript側では「クラスを付ける/外す」だけで開閉できるようにしておくと、実装がシンプルになります。
ステップ3:Modalを開く・閉じるための基本ユーティリティ
次に、JavaScriptでModalを開く・閉じるためのユーティリティを作ります。
基本ユーティリティ
export const ModalController = {
open(modalId) {
const el = document.getElementById(modalId);
if (!el) return;
el.classList.add("is-open");
el.setAttribute("aria-hidden", "false");
},
close(modalId) {
const el = document.getElementById(modalId);
if (!el) return;
el.classList.remove("is-open");
el.setAttribute("aria-hidden", "true");
},
};
JavaScript使用例
// Modalを開く
ModalController.open("my-modal");
// Modalを閉じる
ModalController.close("my-modal");
JavaScriptこのようにしておけば、
- HTML側では
id="my-modal"を付けておくだけで、 - JavaScriptから簡単に開閉できるようになります。
ステップ4:ボタンとModalを紐づける(イベントハンドラ)
Modalは「ボタンを押したら開く」「閉じるボタンを押したら閉じる」という動きが基本です。
HTML側の例
<button type="button" data-modal-open="my-modal">
詳細を見る
</button>
<div class="modal-backdrop" id="my-modal" aria-hidden="true">
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">詳細情報</h2>
<button class="modal-close" type="button" aria-label="閉じる">×</button>
</div>
<div class="modal-body">
ここに詳細情報が入ります。
</div>
<div class="modal-footer">
<button type="button" class="modal-cancel">キャンセル</button>
<button type="button" class="modal-ok">OK</button>
</div>
</div>
</div>
JavaScriptでイベントを設定する
function setupModalTriggers() {
// 開くボタン
document.querySelectorAll("[data-modal-open]").forEach((btn) => {
const modalId = btn.getAttribute("data-modal-open");
btn.addEventListener("click", () => {
ModalController.open(modalId);
});
});
// 閉じるボタン(× や キャンセル)
document.querySelectorAll(".modal-backdrop").forEach((backdrop) => {
const modalId = backdrop.id;
// ×ボタン
const closeBtn = backdrop.querySelector(".modal-close");
if (closeBtn) {
closeBtn.addEventListener("click", () => {
ModalController.close(modalId);
});
}
// キャンセルボタン
const cancelBtn = backdrop.querySelector(".modal-cancel");
if (cancelBtn) {
cancelBtn.addEventListener("click", () => {
ModalController.close(modalId);
});
}
});
}
document.addEventListener("DOMContentLoaded", setupModalTriggers);
JavaScriptこれにより、
data-modal-open="my-modal"を持つボタンをクリックするとmy-modalが開く- Modal内の
×やキャンセルボタンをクリックすると閉じる
という基本的な動きが実現できます。
ステップ5:業務でよくある「確認Modal」のテンプレート
業務システムでは、「削除してよいですか?」のような確認Modalが頻出します。
HTMLテンプレート例
<button type="button" data-modal-open="delete-confirm-modal">
削除
</button>
<div class="modal-backdrop" id="delete-confirm-modal" aria-hidden="true">
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">削除確認</h2>
<button class="modal-close" type="button" aria-label="閉じる">×</button>
</div>
<div class="modal-body">
このレコードを削除します。よろしいですか?
</div>
<div class="modal-footer">
<button type="button" class="modal-cancel">キャンセル</button>
<button type="button" class="modal-ok">削除する</button>
</div>
</div>
</div>
JavaScriptで「OKボタンの動作」を紐づける
function setupDeleteConfirmModal(onConfirm) {
const backdrop = document.getElementById("delete-confirm-modal");
if (!backdrop) return;
const okBtn = backdrop.querySelector(".modal-ok");
const modalId = backdrop.id;
if (okBtn) {
okBtn.addEventListener("click", () => {
ModalController.close(modalId);
onConfirm(); // 実際の削除処理を呼び出す
});
}
}
// 使用例
document.addEventListener("DOMContentLoaded", () => {
setupModalTriggers();
setupDeleteConfirmModal(() => {
// ここに削除処理を書く
console.log("削除処理を実行します");
});
});
JavaScriptポイント:Modalは「ユーザーに確認させる場」として使うことが多く、 OKボタンの動作を関数として渡せるようにしておくと、再利用性が高まります。
ステップ6:アクセシビリティ(キーボード操作・フォーカス制御)への配慮(重要な深掘り)
Modalは「画面の上に重ねて表示されるUI」なので、 アクセシビリティ(特にキーボード操作)への配慮が重要です。
押さえておきたいポイント
- Modalを開いたときに、フォーカスをModal内の要素に移す
- 例:最初のボタンや閉じるボタンにフォーカスを当てる。
- Escキーで閉じられるようにする(必要に応じて)
- ユーザーがキーボードだけで操作できるようにする。
- Modalが開いている間は、背景側の要素にフォーカスが移動しないようにする
- 本格的な「フォーカストラップ」は少し難しいですが、 少なくとも「Tabキーで背景に飛んでしまう」状態は避けたいです。
フォーカス制御の簡易実装例
export const ModalController = {
open(modalId) {
const el = document.getElementById(modalId);
if (!el) return;
el.classList.add("is-open");
el.setAttribute("aria-hidden", "false");
// 最初のフォーカス対象を決める
const focusTarget =
el.querySelector(".modal-ok") ||
el.querySelector(".modal-close") ||
el.querySelector("button") ||
el;
if (focusTarget && typeof focusTarget.focus === "function") {
focusTarget.focus();
}
},
close(modalId) {
const el = document.getElementById(modalId);
if (!el) return;
el.classList.remove("is-open");
el.setAttribute("aria-hidden", "true");
},
};
JavaScriptEscキーで閉じる処理の例
function setupModalEscClose(modalId) {
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
ModalController.close(modalId);
}
});
}
// 使用例
document.addEventListener("DOMContentLoaded", () => {
setupModalEscClose("my-modal");
});
JavaScriptポイント:Modalは「ユーザーの操作を一時的にそこへ集中させるUI」なので、 キーボード操作でも自然に扱えるようにしておくことが、業務システムでは特に重要です。
ステップ7:複数Modalを扱うときの設計(シンプルさを保つ)
業務システムでは、複数種類のModalを使うことがよくあります。
- 削除確認Modal
- 詳細表示Modal
- 設定変更Modal
このとき、設計が複雑になりすぎないようにするために、 次のような方針を取るとよいです。
方針
- 「1つのModalに1つの役割」 を持たせる
- Modalごとに
idを付けて、ユーティリティから開閉する - 共通部分(開閉・フォーカス制御)は
ModalControllerに集約する - イベント固有の処理(削除、保存など)は別関数として切り出す
例:複数Modalのセットアップ
document.addEventListener("DOMContentLoaded", () => {
setupModalTriggers();
setupDeleteConfirmModal(() => {
console.log("削除処理");
});
setupSettingsModal(() => {
console.log("設定保存処理");
});
});
function setupSettingsModal(onSave) {
const backdrop = document.getElementById("settings-modal");
if (!backdrop) return;
const saveBtn = backdrop.querySelector(".modal-ok");
const modalId = backdrop.id;
if (saveBtn) {
saveBtn.addEventListener("click", () => {
ModalController.close(modalId);
onSave();
});
}
}
JavaScriptステップ8:絶対に避けるべき危険な・使いづらいパターンを明確にしておく
1. Modalを「DOMの書き換えだけ」で毎回生成する
// 毎回 innerHTML でModalを生成する例(推奨しません)
document.body.innerHTML += `
<div class="modal-backdrop">...</div>
`;
JavaScriptこれは、
- 同じModalが何度もDOMに増殖する
- イベントハンドラが重複して設定される
- メモリリークや予期しない挙動の原因になる
などの問題があります。
結論:Modalは基本的に「HTMLとしてあらかじめ用意しておき、開閉だけを制御する」方が安全で分かりやすいです。
2. Modalを閉じる手段がない
- 閉じるボタンがない
- Escキーでも閉じられない
- 背景クリックでも閉じられない
これは、ユーザーが「Modalに閉じ込められる」状態になり、 非常に使いづらいUIになります。
3. 背景側の操作ができてしまう
- Modalが開いているのに、背景のボタンがクリックできる
- 背景のフォームにフォーカスが移ってしまう
これは、Modalの意味が薄れてしまい、 ユーザーの操作が混乱しやすくなります。
ステップ9:チームで共有するための「Modal設計ルール」をコードとドキュメントに刻む
コードコメントで明示する
// 注意:
// Modalは、画面の上に重ねて表示されるUI部品です。
// ModalController を使って開閉を制御し、
// .modal-backdrop に is-open クラスを付け外しすることで表示状態を切り替えてください。
// Modalには必ず閉じる手段(×ボタン、キャンセルボタン、Escキーなど)を用意し、
// ユーザーが操作に行き詰まらないようにしてください。
JavaScriptレビュー時のチェックポイント
- ModalのHTML構造が統一されているか(backdrop・header・body・footer)
- 開閉処理が
ModalControllerに集約されているか - 閉じる手段が複数用意されているか(×、キャンセル、Escなど)
- キーボード操作でModalを扱えるか(フォーカス制御)
こうしたルールをチームで共有することで、 「Modalごとにバラバラな実装」「閉じられないModal」などの問題を防ぎやすくなります。
まとめ:Modalを開くユーティリティは「ユーザーの集中を一時的に一点に集めるための、実務的で欠かせないUI技術」です
Modalを開くためのJavaScriptユーティリティと設計を導入することで、次のような効果があります。
- どの画面でも同じ方法でModalを開閉できる
- 確認ダイアログや詳細表示などを簡単に追加できる
- アクセシビリティや使いやすさを保ったまま、複数Modalを運用できる
- チーム全体で「Modalの安全で分かりやすい使い方」を共有しやすくなる
業務システムでは、Modalは「ユーザーの重要な判断を支える場」として使われることが多いです。
そのModalを、きちんとしたユーティリティと設計で扱うことは、 ユーザー体験とシステムの信頼性を高めるうえで、とても実務的で重要な技術だと言えます。

