第3章-5節: 入れ子モーダル - モーダルの中にさらにモーダル?

モーダルの基本的な使い方やスタイリング方法が分かってきたね!情報を効果的に見せるモーダルは、ウェブサイトの使いやすさを向上させるのにとても役立つ。

でも、時には「モーダルの中で、さらに詳しい情報を別のモーダルで見せたいな」とか、「いくつかのステップに分けて操作を進めてほしいな」なんて思うこともあるかもしれない。そんな時に活躍するのが「入れ子モーダル(ネストされたモーダル)」なんだ。今回は、このちょっと高度なテクニックに挑戦してみよう!

겹쳐진 상자 入れ子モーダルとは?

入れ子モーダルとは、その名の通り、あるモーダルウィンドウの中から、さらに別のモーダルウィンドウを開く仕組みのこと。まるで、ロシアのマトリョーシカ人形みたいに、モーダルがモーダルを内包するようなイメージだね。

ユーザーが最初のモーダル(親モーダル)内のボタンなどをクリックすると、その親モーダルの上に新しいモーダル(子モーダル)が重なって表示されるんだ。通常、子モーダルが表示されている間は、親モーダルも背景の一部となって操作できなくなるよ。

🤔 どんな時に便利? 入れ子モーダルの使いどころ

入れ子モーダルは、上手に使うとユーザー体験を向上させることができるけど、使いすぎるとかえって混乱を招くこともあるから注意が必要だよ。代表的な使いどころはこんな感じだ。

  • 段階的な情報提示: 最初は大まかな情報や選択肢を親モーダルで見せて、ユーザーが選んだ項目に関するより詳細な情報を子モーダルで提示する。
  • 複雑な設定フロー: いくつかのステップに分かれた設定作業を、各ステップごとにモーダルを分けて表示する。例えば、「設定項目Aを選ぶ」→(子モーダルで)「Aに関する詳細設定をする」といった流れ。
  • 確認の確認 (慎重に!): 例えば、「本当に重要なデータを削除しますか?」(親モーダル) →「はい」→「最終確認です。この操作は元に戻せません。本当に削除しますか?」(子モーダル)。ただし、これはユーザーをうんざりさせる可能性もあるから、本当に必要な場合だけにしよう。
  • 複数の詳細オプション: 親モーダルでいくつかのオプションを提示し、ユーザーがどれかを選ぶと、そのオプションに特化した詳細設定や追加情報を子モーダルで表示する。

🛠️ 入れ子モーダルの作り方と考え方

入れ子モーダルを作るには、HTML、CSS、JavaScriptそれぞれで少し工夫が必要になるよ。

1. HTMLの構造

まず、表示したいモーダルの数だけ、それぞれのモーダル要素(オーバーレイとコンテンツのセット)をHTML内に用意しておく。それぞれに異なるidを付けて区別できるようにしよう。

<!-- 最初のモーダル (親モーダル) -->
<div class="modal-overlay" id="modalOverlay1">
  <div class="modal-content" id="modalContent1">
    <div class="modal-header">
      <h3 class="modal-title">親モーダル</h3>
      <button class="modal-close-button" data-modal-id="modalOverlay1">×</button>
    </div>
    <div class="modal-body">
      <p>これが最初のモーダルです。</p>
      <button id="openNestedModalBtn">入れ子モーダルを開く</button>
    </div>
    <div class="modal-footer">
      <button class="btn-secondary" data-modal-id="modalOverlay1">閉じる</button>
    </div>
  </div>
</div>

<!-- 2番目のモーダル (子モーダル) -->
<div class="modal-overlay" id="modalOverlay2"> <!-- 別のオーバーレイ -->
  <div class="modal-content" id="modalContent2">
    <div class="modal-header">
      <h3 class="modal-title">子モーダル</h3>
      <button class="modal-close-button" data-modal-id="modalOverlay2">×</button>
    </div>
    <div class="modal-body">
      <p>これが入れ子になったモーダル(子モーダル)です!</p>
    </div>
    <div class="modal-footer">
      <button class="btn-secondary" data-modal-id="modalOverlay2">閉じる</button>
    </div>
  </div>
</div>

ここでは、各モーダルが独自のオーバーレイを持つようにしているけど、CSSのz-indexをうまく使えば、オーバーレイは1つだけでも実現できるよ(その場合、JavaScriptでの管理が少し複雑になる)。

2. CSSでのスタイリングと重ね順 (z-index)

見た目の基本スタイルは、これまで作ってきたモーダルと同じで大丈夫。入れ子モーダルで特に重要なのが、重ね順 (z-index) の管理だ。

後から開くモーダル(子モーダル)が、必ず親モーダルの手前に表示されるように、子モーダルのz-index値を親モーダルよりも大きく設定する必要があるんだ。

/* 親モーダルのオーバーレイ */
#modalOverlay1 { z-index: 1000; }
#modalOverlay1 .modal-content { z-index: 1010; } /* 親モーダルのコンテンツ */

/* 子モーダルのオーバーレイ */
#modalOverlay2 {
  z-index: 1005; /* 親のコンテンツより手前、子のコンテンツより後ろ */
  background-color: rgba(0, 0, 0, 0.3); /* 少し薄くして重なりを表現 */
}
#modalOverlay2 .modal-content { z-index: 1020; } /* 子モーダルのコンテンツ (最前面) */

このように、z-indexの値を段階的に大きくしていくことで、モーダルが正しく重なって表示されるよ。

3. JavaScriptによる制御

JavaScriptでは、それぞれのモーダルを開閉するためのロジックが必要になる。

  • 親モーダル内の「入れ子モーダルを開く」ボタンがクリックされたら、子モーダルを開く関数を呼び出す。
  • 子モーダルを閉じるときは、子モーダルだけを非表示にするのが一般的(親モーダルは表示されたまま)。
  • Escキーを押したときは、一番手前に表示されているモーダルから順に閉じていくように制御すると、ユーザーにとって自然な操作になる。

これを実現するには、現在どのモーダルが開いているかを把握したり、開いているモーダルのリストを管理したりする必要が出てくる場合がある。単純な2段階の入れ子なら、そこまで複雑にしなくても作れるよ。

4. アクセシビリティの考慮

入れ子モーダルの場合も、アクセシビリティは非常に重要だ。特に以下の点に注意しよう。

  • フォーカストラップ: キーボードのフォーカスが、必ず一番手前に表示されているモーダルの中に留まるようにする。背景のモーダルやページ本体にフォーカスが移ってしまわないように。
  • aria-modal="true": 各モーダルコンテンツ要素にこの属性を指定すると、スクリーンリーダーに対して「このモーダルが表示されている間は、他の部分は操作不能ですよ」と伝えられる。
  • 背景コンテンツの非表示化: 子モーダルが表示されている間、親モーダルはスクリーンリーダーから一時的に隠す(例えばaria-hidden="true"を使う)と、混乱を防げる場合がある。

これらのアクセシビリティ対応は、モーダル専用のアクセシビリティのページ (03-07) で、もっと詳しく見ていくよ。

⚠️ 実装上の注意点

  • z-index地獄に注意: モーダルが増えてくると、z-indexの管理が複雑になりがち。計画的に値を設定しよう。
  • ユーザーを迷わせない: モーダルを何重にも重ねすぎると、ユーザーは「今どこにいるんだっけ?」と混乱してしまう。本当にその入れ子構造が必要か、UIデザインの観点からよく考えよう。通常は2段階、多くても3段階くらいまでが限度かも。
  • Escキーの挙動: ユーザーはEscキーでモーダルを閉じられることを期待していることが多い。入れ子の場合は、一番手前のものから順番に閉じるのが自然だよ。

デモ:入れ子モーダルを体験!

さあ、実際に2段階の入れ子モーダルがどんな風に動くか見てみよう!下のボタンをクリックして、最初のモーダルを開き、その中のボタンでさらに子モーダルを開いてみてね。

{/* */} {/* */} {/* */}

🇬🇧英語の豆知識コーナー

重ね順や状態管理に関する言葉を覚えよう!

  • Nested

    意味:入れ子になった、ネストされた

    Original: We are creating a nested modal structure for a multi-step process.

    意訳:複数ステップのプロセスのために、入れ子になったモーダル構造を作成しています。

  • z-index

    意味:z-index(CSSのプロパティで、要素の重ね合わせの順番を指定する)

    Original: A higher z-index value means the element will be displayed in front of elements with a lower value.

    意訳:z-indexの値が大きいほど、その要素は値が小さい要素の前面に表示されます。

  • Stacking Context

    意味:スタッキングコンテキスト(要素がどのように重なるかを決定するHTML要素のグループ)

    Original: Elements with a 'position' value other than 'static' and a z-index can create a new stacking context.

    意訳:「static」以外の「position」値とz-indexを持つ要素は、新しいスタッキングコンテキストを作成できます。

  • State Management (for modals)

    意味:(モーダルの)状態管理(どのモーダルが開いているか、などの情報を管理すること)

    Original: For complex UIs with multiple modals, robust state management is important.

    意訳:複数のモーダルを持つ複雑なUIでは、堅牢な状態管理が重要です。

まとめ

今回は、モーダルの中からさらにモーダルを開く「入れ子モーダル」の作り方と、その際の注意点について学んだね。

  • 複数のモーダル要素を用意し、JavaScriptでそれぞれの開閉を制御する。
  • CSSのz-indexをうまく使って、モーダルが正しく重なって表示されるようにする。
  • ユーザーが混乱しないように、入れ子の深さやUIデザインには気を配ろう。
  • Escキーの挙動やアクセシビリティ(特にフォーカス管理)も大切。

入れ子モーダルは、うまく使えば複雑な情報や操作を分かりやすく整理できる強力なテクニックだ。でも、常に「ユーザーにとって本当に分かりやすいかな?」と考えることを忘れずにね!

次のページでは、表示されたモーダルウィンドウをマウスでドラッグして移動できるようにする方法を学ぶよ。お楽しみに!