今回はモーダルウィンドウをプラグイン無しで作成する方法をまとめます!
モーダルウィンドウはWebサイトによく使われるUIですが、意外に実装が難しいんですよね。
同ページ内に複数モーダルを設置する方法まで、基礎的な内容は解説していますので、不安な方は是非参考にしていただけると嬉しいです!
モーダルウィンドウ とは
モーダルウィンドウとは、操作が完了するまで親ウィンドウへの操作を受け付けなくさせるタイプのウィンドウのことである。
モーダルウィンドウが表示されると、その中で指定された操作を完了するかキャンセルするかして、そのウィンドウを閉じない限り、親ウィンドウ側に対する操作ができないようになる。このため、モーダルウィンドウはユーザーに特定の操作をさせたり、確認を促したりといった目的で用いられることが多い。
Weblio 辞書 > コンピュータ > IT用語辞典 > モーダルウィンドウの意味・解説
下の動画のように特定の要素をクリックやタップをすると、別の小窓が浮かび上がって表示されるUIです。
主に会員登録やログインフォーム、申込フォームなど、ユーザーに対して重要な動作を求める時に用いられます。
メイン画面の閲覧や操作を強制的に遮断することになるため、モーダルウィンドウが多様されているWebサイトやアプリはユーザー体験的にはあまり好ましくありません。
重要なポイントに絞って採用した方が良いUIデザイン、と認識を持っておいた方が良いかと思います。
コードの構成
- ページ(基礎階層)にウィンドウを表示させるボタン(リンク)を作成
- モーダルウィンドウを作成
- オーバーレイを作成(必要であれば)
基本形の作成
まずはデモサイトもご覧ください。かなり簡素な内容ですが基本形の形を載せています。
先にHTMLの全体を載せておきます。
<!-- オーバーレイ -->
<div id="overlay" class="overlay"></div>
<!-- モーダルウィンドウ -->
<div class="modal-window">
<!-- 閉じるボタン -->
<button class="js-close button-close">Close</button>
</div>
<!-- モーダルを開くボタン -->
<button class="js-open button-open">open</button>
モーダルをオープンさせるボタンの作成
HTML
<button class="js-open button-open">open</button>
クラスは二つ、jQueryで指定する方はid指定してもいいです。js-openクラスはjQueryで制御する用、button-openクラスはCSSでスタイリングする為のクラスとしています。
CSS
/* リセットCSSは割愛します */
/* 開くボタン */
.button-open {
display: block;
margin: 0 auto;
width: 20rem;
padding: 1em;
background-color: #3140c9;
color: #eaeaea;
border-radius: 20rem;
cursor: pointer;
}
これだけで下のようなボタンになります。
次にクリックで表示させる枠を作成します。
モーダル表示するウィンドウを表示
HTML
<div class="modal-window">
<button class="js-close button-close">Close</button>
</div>
CSS
/* モーダルウィンドウ */
.modal-window {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
background-color: #dfdddd;
border-radius: 5px;
z-index: 11;
padding: 2rem;
}
/* 閉じるボタン */
.button-close {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
padding: 1em;
background-color: #c96931;
color: #eaeaea;
border-radius: 20rem;
cursor: pointer;
}
modal-windowは画面中央に配置させてます。多くのWebサイトでもモーダルは画面中央に表示れていることが多いです。
11行目にz-indexを指定していますが、これはメイン画面より重ね位置を上にしておくために記述します。順番前後しますが、次に用意するオーバーレイをz-index:10にする予定なので、モーダルウィンドウ はその一つ上の階層に置く為にとりあえず11としました。
ここまででこんな感じになります。
ただ、モーダルウィンドウ はクリックされるまで非表示にさせる必要があるで、display: noneを追記しておきます。
.modal-window {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
background-color: #dfdddd;
border-radius: 5px;
z-index: 11;
padding: 2rem;
}
オーバーレイの作成
HTML
<div id="overlay" class="overlay"></div>
オーバーレイは画面全体を暗めの色で覆いかぶせるマスクのようなものです。
スタイリングできればなんでもいいので、とりあえずidとclassだけ指定した空のdivタグを置いておきます。
CSS
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 10;
}
モーダルウィンドウ同様、display: noneで非表示にはしておきます。
position: fixedで左上に基準を合わせてwidthとheightを100%にして画面領域いっぱいを確保します。単位はvwやvhでもいいです。
オーバーレイは10、モーダルウィンドウは11とz-indexで重ね順も指定しています。
スタイリングは完成したので、一旦ここまでのcssをまとめておきます。
/* 開くボタン */
.button-open {
display: block;
margin: 0 auto;
width: 20rem;
padding: 1em;
background-color: #3140c9;
color: #eaeaea;
border-radius: 20rem;
cursor: pointer;
}
/* モーダルウィンドウ */
.modal-window {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
background-color: #dfdddd;
border-radius: 5px;
z-index: 11;
padding: 2rem;
}
/* 閉じるボタン */
.button-close {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
padding: 1em;
background-color: #c96931;
color: #eaeaea;
border-radius: 20rem;
cursor: pointer;
}
/* オーバーレイ */
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 10;
}
ちなみに、オーバーレイやモーダルウィンドウはbodyの直下に配置させておきます。
何かのコンテンツ内のボタンに呼応した内容であったとしても、オーバーレイやモーダルはそのコンテンツの子要素として記述はしません。あくまでモーダルはモーダル、別のブロックとしてカテゴライズする方が自然と思いますので。
jQueryで動きを制御
ここでは載せませんが、jQueryを使うのでCDNコードはHTMLのbodyの閉じタグ前に読み込んでおきましょう!詳しくはこちらから↓
かなりシンプルですが、一応分解して解説します。
$(function () {
$('.js-open').click(function () {
$('#overlay, .modal-window').fadeIn();
});
$('.js-close').click(function () {
$('#overlay, .modal-window').fadeOut();
});
});
js-openクラスをクリックしたら〜というクリックイベントです。
$('.js-open').click(function () {
#overlayと.modal-windowをフェードインさせます。
$('#overlay, .modal-window').fadeIn();
js-closeクラスをクリックしたら〜というクリックイベントです。
$('.js-close').click(function () {
overlayと.modal-windowをフェードアウトさせます。
$('#overlay, .modal-window').fadeOut();
これで基本形は完成です。
閉じるボタン以外をクリックしてもモーダルを閉じれるように
モーダル内の閉じるボタンが小さい場合や、モーダルウィンドウ自体が大きい場合、ウィンドウを閉じるのに手間がかかると感じられます。
なるべく簡単に閉じれるように、モーダルウィンドウの外をクリックしても、ウィンドウが閉じるようになっているUIも多くあります。
そこでオーバーレイの部分をクリックしてもモーダルが非表示になるようなデモを用意しました。
モーダルを表示させたあと、オーバーレイ部分をクリックしてもモーダルが閉じることがわかるかと思います。
仕組みは特に難しくなく、ウィンドウをクローズさせる7行目のセレクタに#overlayを追加するだけで実現できます。
$(function () {
$('.js-open').click(function () {
$('#overlay, .modal-window').fadeIn();
});
// オーバーレイクリックでもモーダルを閉じるように
$('.js-close , #overlay').click(function () {
$('#overlay, .modal-window').fadeOut();
});
});
これでオーバーレイ(画面全体)をクリックしてもモーダルが閉じるようになりました。
ボタンとモーダルが複数ある場合
オープン用ボタンと、モーダルウィンドウが複数あるサイトも存在すると思います。
この時、表示させるモーダルウィンドウが1パターンだったら何も問題ないのですが、複数ある場合は「このボタンを押したらこのウィンドウを表示させる」といった紐付けが必要になります。
どういうことかは、先にデモをご覧いただいた方が分かるかもしれません。
open1をクリックしたらモーダルNo.1が、open4をクリックしたらモーダルNo.4が表示されています。
これを実現するためにdata属性(カスタムデータ属性)を使います。
data属性(カスタムデータ属性)とは
HTMLに独自に変数のような値を持たせることができる属性です。js(jQuery)やCSSなどから読み込むことで、data属性を指定したスタイルや挙動の制御ができます。
クラスやidで振り分けても同じようなことは実現できますが、記述も長くなり管理も煩雑になりますし、本来の使い処を考えると適切ではありません。
[linkcard url=”https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/data-*”]
ということでHTMLとjQueryのコード内容にdata属性を反映させていきます。
HTML
<!-- オーバーレイ -->
<div id="overlay" class="overlay"></div>
<!-- モーダルウィンドウ1 -->
<div class="modal-window" data-id="modal1">
<p>モーダルNo.1</p>
<button class="js-close button-close">Close</button>
</div>
<!-- モーダルウィンドウ2 -->
<div class="modal-window" data-id="modal2">
<p>モーダルNo.2</p>
<button class="js-close button-close">Close</button>
</div>
<!-- モーダルウィンドウ3 -->
<div class="modal-window" data-id="modal3">
<p>モーダルNo.3</p>
<button class="js-close button-close">Close</button>
</div>
<!-- モーダルウィンドウ4-->
<div class="modal-window" data-id="modal4">
<p>モーダルNo.4</p>
<button class="js-close button-close">Close</button>
</div>
<!-- ボタン1 -->
<div class="wrap">
<button class="js-open button-open" data-id="1">Open1</button>
</div>
<!-- ボタン2 -->
<div class="wrap">
<button class="js-open button-open" data-id="2">Open2</button>
</div>
<!-- ボタン3 -->
<div class="wrap">
<button class="js-open button-open" data-id="3">Open3</button>
</div>
<!-- ボタン4 -->
<div class="wrap">
<button class="js-open button-open" data-id="4">Open4</button>
</div>
モーダルウィンドウのdivタグに data-id=”modal○(○は数字)と追記してます。
また、 buttonタグには data-id=”○”(○は数字)と追記します。
この時リンクさせたいボタンとモーダルは丸の数字を一緒にしておきます。
jQuery
js-openクラスのクリックイベント内に3行目を追記、4行目にはdata-idの読み込みを追記しています。
$(function () {
$('.js-open').click(function () {
var id = $(this).data('id'); // 何番目のキャプション(モーダルウィンドウ)か認識
$('#overlay, .modal-window[data-id="modal' + id + '"]').fadeIn();
});
// オーバーレイクリックでもモーダルを閉じるように
$('.js-close , #overlay').click(function () {
$('#overlay, .modal-window').fadeOut();
});
});
クリックされた(this)要素のdata(‘id’)を取得して、変数idに格納します。先ほどbuttonタグに追記したdata-id内の1〜4のどれかの数字が入るというこですね。
modal-windowの [data-id=”modal’ + id + ‘”] というのが少し分かりづらいかもしれませんが、modal-windowのdivタグにはdata-id=”modal○”としていましたので、○の中に上で取得された変数id(ここだと1〜4の数字)を代入する、という意味になります。
これでクリックされたボタンに設定しておいたdata属性の数字が、モーダルウィンドウ のdata属性の数字として代入され、リンクさせたいウィンドウが開くことになります。
モーダルウィンドウ表示中は背景はスクロールさせない
モーダルウィンドウ表示時は背景(メイン画面)も動かないように制御しておいた方がいいです。
モーダルウィンドウ自体が大きく、縦スクロールが発生する場合なんかは特に、操作時に誤って後ろのメイン画面がスクロールするとユーザーにもストレスになります。
これもCSSとjQueryに少し加えて、背景ロックが実現でいます。
こちらもデモをご覧いただき、モーダル表示中は背景画面(メイン画面)がロックされることを確認ください。
CSS
/* 表示領域外へはスクロールさせない */
.no_scroll {
overflow: hidden;
}
このno_scrollクラスはHTMLには記述せず、jQueryでつけ外しします。
overflow: hiddenは表示されていない画面外の要素を隠す=スクロールさせないため、これを使います。
jQuery
$(function () {
$('.js-open').click(function () {
$("body").addClass("no_scroll"); // 背景固定させるクラス付与
var id = $(this).data('id'); // 何番目のキャプション(モーダルウィンドウ)か認識
$('#overlay, .modal-window[data-id="modal' + id + '"]').fadeIn();
});
// オーバーレイクリックでもモーダルを閉じるように
$('.js-close , #overlay').click(function () {
$("body").removeClass("no_scroll"); // 背景固定させるクラス削除
$('#overlay, .modal-window').fadeOut();
});
});
jQueryに追記したのは3行目と9行目だけです。オープンした時はoverflow: hiddenさせ、閉じる時はそのクラスを外しているだけです。
まとめ
モーダルウィンドウ の作成方法について、段階を踏みながら解説してみました。
ウィンドウのデザインが変わるくらいで仕組みとしてはそこまでパターンは無いUIなので、これを機会にサクッと作れるようにしておきましょう!
別記事でもjQueryを使ったUIの実装方法解説をまとめているので、ご興味のある方は覗いてみて下さい!
実はプラグインを使った方が格段に簡単なパターンもあったりするので、ここについてはまたの機会にまとめていければと思います。
また、当記事を読まれている方の中にはWeb制作初学者の方もいるかと思います。デザインやコーディングの基礎知識を学びたい方向けの記事を用意しているので是非見ていってください!
PENGIN無料コーディング課題
オススメ書籍紹介
オススメUdemy講座紹介