初心者でも簡単!モーダルウィンドウの作り方

      2017/05/11

モーダルウィンドウは、コンテンツを浮かび上がるようにポップアップ表示させることができます。
ヘルプやアラートなど、ちょっとしたメッセージを表示するときに、確認ダイアログだとちょっとダサい・・・。そんな時に使えると便利なのがモーダルウィンドウです。

モーダルウィンドウのデモ

テキストリンクをクリックすると、モーダルウィンドウが表示されます。コンテンツ内の閉じるボタン、または背景のオーバーレイをクリックすると、モーダルウィンドウを閉じます。

クリックするとモーダルウィンドウを開きます。

モーダルウィンドウの作り方

コンテンツの作成

まずは、モーダルウィンドウ内に表示させるコンテンツを作成します。あとから変更することができるので、現段階ではこだわる必要はありません。

手前に表示させる

コンテンツを囲むdiv要素にはz-indexの値を設定します。z-indexとは、「手前、奥」の概念です。z-indexの値が高いほど、そのコンテンツは、値が低い他のコンテンツよりも手前に表示されることになります。
初期値は0(または親要素と同じ)です。

モーダルウィンドウのコンテンツは、通常表示されている他のコンテンツ(z-index:0)と、次項で作るオーバーレイ(z-index:1)よりも手前に表示させるので、2を指定しておきましょう。もし、他のライブラリなどを導入している関係で手前に上手く表示されない場合は、9999にするなど調整して下さい。

position:fixedを指定しておきます。これは、「対象の要素を指定した位置に固定する」という命令です。これは、ページをスクロールしても、ずっと画面上のその位置に止まり続けるという意味です。

画面上のどの位置に固定するかは、top(画面上部から何ピクセルか)と、left(画面左部から何ピクセルか)などで指定する仕組みですが、後ほど、jQueryによって動的に指定するので、現時点では指定しません。

オーバーレイの作成

続いて、オーバーレイの部分を作成していきます。先ほどのモーダルウィンドウのデモを表示した時に、周りの背景が半透明のグレーになっていて、そこをクリックするとウィンドウが閉じれたかと思います。
あの部分のことをオーバーレイと言います。

HTMLの部分に関しては、後ほどJavaScriptにて動的に生成しますので、特にHTMLファイルに記述しておく必要はありません。あとからこのHTMLを呼び出すということを覚えておいて下さい。

今回のオーバーレイは、ページ全体ではなく画面全体を覆います。そのため、width:100%とheight:120%を指定し、さらにposition:fixedで位置を固定しておきましょう。

heightの指定を120%にしているのは、スマホ対策です。iPhoneではスクロールをすると上下のナビバーが隠れる仕組みになっているため、heightの値が変わってしまい、オーバーレイが画面の高さよりも小さくなってしまうという不具合が起こります。それを解消するため、余裕を持って120%の値を指定しています。

色を#D36015というような16進数(Hex)ではなく、rgbaで指定することで、不透明度を加えることができます。モーダルウィンドウを表示した時、コンテンツが背景にうっすらと映っている状態にするのに必要です。今回は、色を黒、不透明度0.75を指定したものです。()内の第1〜3引数がRGB指定による色、第4引数が不透明度を表します。

モーダルウィンドウを表示する

ここからいよいよ、JavaScriptを取り扱っていきます。jQueryを利用するので、

<head></head>内にあらかじめ上記を記述しておきましょう。

ボタンを用意する

モーダルウィンドウを呼び出すためのボタンを用意しておきましょう。

クリックイベントの設定

ボタンをクリックした時にモーダルウィンドウを表示させるイベントを設定します。

オーバーレイを表示する

ボタンがクリックされた時にオーバーレイを表示するように設定していきます。さきほど、HTMLはjQueryで自動生成させると説明しましたが、具体的には、以下のように行います。

「クリックイベントの設定」でお話しした箇所に上記のコードを記述します。

appendは対象の要素内の最後に、指定したHTMLを追加する命令です。上記では、body要素内の最後に、オーバーレイのHTMLコードを追加しています。さらに、初期ではdisplay:hiddenで非表示状態なのを、fadeInにより、じんわりと表示させています。

コンテンツをセンタリングする

コンテンツを画面の真ん中に表示させるにはどうすればいいかを考えてみましょう。position:fixedのtop(画面上部から何ピクセル離れているか)とleft(画面左部から何ピクセル離れているか)の値を、上手く設定します。
例えば、画面幅が1000pxあって、コンテンツ幅が200pxある場合、真ん中に持ってくるには、left(片側の余白の値)に400pxを設定します。左端から400px離せばいいというわけです。縦幅も同じですね。「片側の余白」は次の計算で求めることができます。

(画面幅 - コンテンツ幅) ÷ 2

横幅、縦幅を求めてセンタリングするには、次の通り、処理しましょう。複数の場所から呼び出せるように、centeringModalSyncer()という関数にしてあります。このように、モーダルウィンドウを開いた時の画面幅に合わせてtopとleftの値を設定してやることで、センタリングが実現します。

モーダルウィンドウを終了する

モーダルウィンドウを終了させるクリックイベントを設定します。

クリックイベントの設定

オーバーレイ(#modal-overlay)と閉じるボタン(#modal-close)、2つの要素に同じクリックイベントを設定します。それには、セレクタをカンマで区切って、次のように記述します。

click()の直前にあるunbind()は、対象の要素にそれまで設定されていたイベントをクリアする命令です。

フェードアウトさせる

オーバーレイとコンテンツをフェードアウトで非表示にした後に、HTML上からオーバーレイのHTMLを削除します。それには次の通り、命令しましょう。

fadeOut()の第2引数に関数を指定することで、その関数がフェードアウトしたタイミングで実行されます。remove()は対象の要素をHTML上から削除する命令です。

まとめ モーダルウィンドウのサンプルコード

以上でモーダルウィンドウは完成です。
他にもコードを変えることでいろいろな使い道ができるので、いろいろといじってみてください。

最後に、今回のモーダルウィンドウのサンプルコードをまとめて記載しておきます。

HTMLのサンプル

CSSのサンプル

JavaScriptのサンプル

【追記】モーダルウィンドウのスクロール時に背景を固定させるには?

先日コメントにて、「モーダルウィンドウをスクロールした時に背景までスクロールされてしまうので、背景を固定するにはどうしたらよいでしょうか。」といった内容のご質問を受けましたので、追記させていただきます。

下記テキストリンクをクリックすると、モーダルウィンドウが表示されます。

ここで表示されるモーダルウィンドウでは、背景部分は固定され、モーダル内部についてはスクロール可能としています。コンテンツ内の閉じるボタン、または背景のオーバーレイをクリックすると、モーダルウィンドウを閉じます。

クリックするとモーダルウィンドウ(背景固定)を開きます。

背景固定版のサンプルコード

CSSのサンプル

先ほどのCSSと異なるのは、#modal-content の部分だけとなります。

モーダル部分の高さを指定するために「height:40%;」をサンプルでは追加しています。

また、モーダル内部をスクロール可能にするため、「overflow-y: scroll;」を追加しています。

JavaScriptのサンプル

先ほどのJavaScriptに追加する部分は4か所です。

まず、背景を固定するときに指定する高さを取得し変数に格納するため「var pointY;」で変数を追加します。

次に、モーダルウィンドウ表示用のボタンをクリックしたときに、背景を固定させるため、

を「$("#modal-open").click(function(){」以降に追加します。

「pointY = $(window).scrollTop();」では先ほど追加した変数に、現時点でのy座標を取得しています。

次に、背景部分にあたるbodyに対し、CSSを追加します。

「'top': -pointY」を追加しておかないと、「top:0」となり、最上部へ移動してしまうので、現時点の座標にとどめておくために、「'top': -pointY」を追加します。

これで、背景固定は完了です。

続いて、固定解除のために、オーバーレイ部分もしくは閉じるボタンをクリックしたときの処理として、「releaseScrolling();」を追加します。

記述場所は、「$('#modal-overlay-fixed').remove() ;」のあとが良いでしょう。

この、「releaseScrolling();」の処理として、「$("#modal-open").click(function(){ ~~~ } ) ;」のあとに

を追加します。

ここで、先ほど背景を固定するためにbody要素に対して行ったCSSの記述をリセットしています。

「$(window).scrollTop(pointY);」を指定することによって、画面固定解除後も現在の位置を維持しています。

以上で、モーダルウィンドウ表示時のスクロールでも背景を固定することができます。

 - jQuery・JavaScript