【HTML・CSS・jQuery】一から理解するモーダルウィンドウの作り方

window HTMLコーダー
モーダルウインドウの作り方を知りたい!できれば自分でカスタムして使いたい!
そのような方の為に、ただ作るだけでなく自分でカスタムできるように解説していきたいと思います。

モーダルウィンドウを構成する部品を理解する

自分が作成するサイトに合わせてモーダルウィンドウをカスタムするためには、モーダルウィンドウがどんな部品で構成されているのか理解するところから始めましょう。

  • モーダルで表示したいウィンドウ
  • オーバレイで表示する黒幕

モーダルウインドウを実装するのは簡単でこの二つをうまく使いこなせばいいだけです。

モーダルで表示したいウィンドウを作る

それでは早速表示させたいウィンドウと、それを押すと表示される元になる部分を作成してみます。

HTML

<div class="open">+詳しく見る</div>
<div class="modal">
    詳細説明<br />
    詳細説明<br />
    詳細説明<br />
    詳細説明<br />
    <div class="close">×閉じる</div>
</div>

CSS

.open, .close {
    border: 1px solid #333333;
    width: 120px;
    cursor: pointer;
    background-color: darkgray;
}

.modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 300px;
    height: 130px;
    background-color: lightgray;
    display: none;
}

JavaScript

$('.open').click(function(){
    $('.modal').fadeIn();
});
$('.close').click(function(){
    $('.modal').fadeOut();
});

この実装で以下の様にボタンが押されたら画面中央にモーダルウィンドウが開くところまでは実装可能です。
modal

解説

jQueryを利用しているため、headタグ内でjQueryのファイルを読み込むことをお忘れなきようご注意ください。

class=openがクリックされた際にclass=modalがフェードイン、class=closeがクリックされた際にclass=modalがフェードアウトするようにjQueryを利用して実装してあります。

class=modalにはどこでクリックしても画面中央に現れるようCSSが設定されています。

openとcloseはとりあえずdivタグにスタイルをあててボタン風にしていますが、ここは該当のclassさえあてておけばaタグだろうがimgタグだろうが何でもOKです。

これだけではモーダルウィンドウを開いたまま他のコンテンツが見えてしまっているため、次にオーバレイを作成します。

オーバレイで表示する黒幕

モーダルウィンドウ以外の場所に黒幕をかぶせるような形になります。実際にはサイト→黒幕→モーダルウィンドウの三層構造になります。

作成は簡単で、ページの最下部あたりに以下を追加し、CSSを当てます。

HTML

<div class="overlay"></div>

CSS

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 1;
}

こちらを表示するとわかると思いますが、元のページの一層上のレイヤーに黒幕が被さっていることが確認できると思います。
modal

元のコンテンツは実質z-index: 0;となっており、z-index: 1;を指定することで一層上に表示させることが可能になります。2,3を増やせば何層にも重ねることが可能です。

これで元のページにあるボタンなどはさわれなくなります。ひとまず現状ではいきなり表示されていると何もできないので、.overlayにdisplay: none;を追加してデフォルト非表示にしておきましょう。

そして次に表示がクリックされた際にオーバーレイを表示し、閉じるがクリックされた際にオーバレイを非表示にする設定をJavaScriptで行います。

JavaScript

$('.open').click(function(){
    $('.modal').fadeIn();
    $('.overlay').fadeIn();
});
$('.close, .overlay').click(function(){
    $('.modal').fadeOut();
    $('.overlay').fadeOut();
});

さきほどのmodalをフェードイン・アウトするように追加するだけなので簡単です。

ついでに黒幕部分を押した場合にもモーダルを閉じるように「$(‘.close, .overlay’)」と変更しています。

こちらを追加した表示が以下の画像です。
modal

モーダルウィンドウに黒幕が被さってしまっています。これはz-indexの指定がないものはデフォルトで0が設定されているからです。

黒幕はz-indexに1を設定していますので、モーダルウィンドウをそれよりも上に表示するには.modalにz-index: 2;を追加すればOKです。
modal

これでモーダルウィンドウが最前面に表示され、閉じるボタンも押せるようになりました。

以上、モーダルウィンドウとオーバーレイの二つの部品を理解すればモーダルの実装はOKです。

複数対応はどうする?

上記の例では一つの表示ボタンと一つのモーダルウィンドウでしたが、これが複数あると対応を考えないといけません。

具体的には以下のような対応で可能です。

  • 開く際に利用しているタグの属性にdata-targetを追加しどのモーダルウィンドウを開くかを指定する
  • モーダルウィンドウにそれぞれ個別のidを指定する
  • jQueryでdata-targetを取得し同名のモーダルウィンドウを表示する

HTML

<div class="open" data-target="modal1">+食事について詳しく見る</div>
<div class="open" data-target="modal2">+部屋について詳しく見る</div>
<div class="modal" id="modal1">
    お食事<br />
    お食事<br />
    お食事<br />
    お食事<br />
    <div class="close">×閉じる</div>
</div>
<div class="modal" id="modal2">
    お部屋<br />
    お部屋<br />
    お部屋<br />
    お部屋<br />
    <div class="close">×閉じる</div>
</div>

JavaScript

$('.open').click(function(){
    const target = '#' + $(this).attr('data-target');
    $(target).fadeIn();
    $('.overlay').fadeIn();
});

開く際にクリックする要素にdata-targetを付与し、JavaScript内で「$(this).attr(‘data-target’)」で値を取得し同名のモーダルウィンドウをフェードインさせています。

閉じる際にはどのモーダルウィンドウにもclass=modalが設定されているので閉じるフェードアウトの処理に変更はありません。

これで正真正銘色々なパターンのモダールウィンドウに対応できるようになったかと思います。

モーダルウィンドウの使いどころ

実際モーダルウィンドウをどこで使うんだ、ということですが以下のようなパターンが多いかと思います。

  • 画像をクリックで詳細を表示やより大きな画像を表示
  • お問い合わせやユーザー登録など項目の少ないフォームを画面遷移させずモーダルで表示する

レストランのサイトでメニュー画像がたくさん並ぶ中、料理の写真をクリックすると料理に関する詳細がモーダルで表示される。

ランディングページから遷移せずにモーダルでメールアドレスだけ入力してすぐにお問い合わせができる。

こんなところでしょうかね。

利点はページ遷移なし

例えば上記の例で言えば、全料理の個別ページなんて作るまでもない細かい表示の場合、モーダルを利用すれば1ページ内に収めることができます。

ランディングページで盛り上がった気分が、次のお問い合わせページに遷移することで冷めてしまうことを防げるかもしれません。

表示するとページが縦に長くなったり、横に長くなったりする補足説明を表示するボタンに収めてページ内の表示をコンパクトに収めるのにも使えます。

ぜひモーダルを習得して色々なページ作りの役に立ててみてください。