こんにちは!コーダーのゆうしです。
「ボタンをクリックしたらポップアップを表示したい」「外側をクリックしたら閉じるようにしたい」という実装、コーディングでよく依頼される場面のひとつです。プラグインを使わずjQueryだけでシンプルに実装できるので、この記事でまとめて解説します。
表示イメージ
See the Pen モーダルイメージ by Yushi nakagaki (@YUSHI-NAKAGAKI) on CodePen.
ボタンクリックでモーダルが開き、閉じるボタンまたはモーダル外側のクリックで閉じる動きになっています。
実装コード
HTML
<div class="area">
<a id="button1" class="button">ウィンドウを開く</a>
<!-- モーダルエリア -->
<div class="popup1 hidden">
<div class="outside"></div>
<div class="content">
<img src="close.png" id="close1" class="close__button">
<p>モーダルの中身です。</p>
</div>
</div>
</div>
<!-- jQuery CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>モーダルの構造は大きく3つの要素で構成されています。
| 要素 | 役割 |
|---|---|
| .popup1 | モーダル全体のラッパー。画面全体を覆う半透明の黒ベタ |
| .outside | 黒ベタ部分のクリック検知用の透明レイヤー |
| .content | モーダルの中身(白いボックス部分) |
id を button1・popup1・close1 と番号で管理しているので、同じ構造をコピーして番号を変えれば複数のモーダルを量産できます。
CSS
/* モーダル全体(オーバーレイ) */
.popup1 {
display: none;
height: 100vh;
width: 100%;
background: rgba(0, 0, 0, 0.25);
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
/* モーダルの中身 */
.content {
line-height: 1.7;
position: fixed;
z-index: 99999;
top: 50%;
left: 50%;
width: 740px;
box-sizing: border-box;
max-width: 92%;
max-height: 92vh;
transform: translate(-50%, -50%);
display: block;
color: #333;
padding: 70px;
background: white;
}
/* 閉じるボタン */
.close__button {
position: absolute;
right: 20px;
top: 20px;
width: 50px;
height: 50px;
cursor: pointer;
}
/* 外側クリック検知レイヤー */
.outside {
position: absolute;
width: 100%;
height: 100%;
z-index: 999;
cursor: pointer;
}
.area {
position: relative;
}CSSのポイントは2点です。
① .popup1 で画面全体を覆う
position: fixed で画面全体に黒い半透明のオーバーレイを敷いています。display: none でデフォルトは非表示にしておき、jQueryで fadeIn() / fadeOut() を切り替えます。
② .outside で外側クリックを検知する
.outside を .content の後ろに全面展開することで、モーダルの中身以外の黒い部分をクリックしたときに閉じる動きを実現しています。z-index の順番が重要で .content(99999)> .outside(999)になっている点に注意してください。
JavaScript(jQuery)
$(function () {
// ボタンクリックでモーダルを開く
$('#button1').on('click', function () {
$('.popup1').removeClass('hidden').fadeIn();
});
// 外側クリックで閉じる
$('.outside').on('click', function () {
$('.popup1').fadeOut();
});
// 閉じるボタンで閉じる
$('#close1').on('click', function () {
$('.popup1').fadeOut();
});
});fadeIn() と fadeOut() でふわっと表示・非表示を切り替えています。アニメーション速度を変えたい場合は fadeIn(300) のようにミリ秒で指定できます。
複数のモーダルを実装する場合
同じページに複数のモーダルを設置したい場合は、それぞれの id を番号で管理します。
<!-- ボタン1 -->
<a id="button1" class="button">モーダル1を開く</a>
<div class="popup1 hidden">~</div>
<!-- ボタン2 -->
<a id="button2" class="button">モーダル2を開く</a>
<div class="popup2 hidden">~</div>$('#button2').on('click', function () {
$('.popup2').removeClass('hidden').fadeIn();
});
$('#close2').on('click', function () {
$('.popup2').fadeOut();
});同じパターンをコピーして番号をずらすだけで量産できます。
躓きやすいポイント
モーダルが表示されない
jQueryが読み込まれていない場合に起こりやすいエラーです。コンソールに $ is not defined と表示される場合はjQueryのCDNが正しく読み込まれているか確認してください。
外側クリックで閉じない
.outside の z-index が .content より高くなっていると、.content がクリックできなくなります。必ず .content(99999)> .outside(999)の順番にしてください。
スクロールが止まらない
モーダルが開いているときに背景がスクロールしてしまう場合は、モーダルを開くタイミングで $('body').css('overflow', 'hidden') を追加し、閉じるときに $('body').css('overflow', '') で解除するとスクロールを止められます。
$('#button1').on('click', function () {
$('.popup1').removeClass('hidden').fadeIn();
$('body').css('overflow', 'hidden'); // スクロール禁止
});
$('.outside, #close1').on('click', function () {
$('.popup1').fadeOut();
$('body').css('overflow', ''); // スクロール解除
});まとめ
jQueryを使えばプラグインなしでシンプルなモーダルウィンドウを実装できます。.outside を使った外側クリックで閉じる動きや、id を番号で管理した複数モーダルの量産まで応用が効くので、ぜひ活用してみてください。
ご不明な点やコーディングのご依頼はお問い合わせからお気軽にどうぞ。

