はじめに
作って学ぶWeb制作の中級編をご覧いただきありがとうございます!!
今回は1ページ内の複数モーダルウィンドウを実装していきます。
モーダルウィンドウは、ユーザーに重要な情報を伝えたり、エラーメッセージを通知する場合などによく使われるUIです。サイトを訪れた際にクーポンや新商品などがモーダルで表示されるのを見かけたことがある方もいると思います。
今回はページ内に複数のモーダルを設置し、それぞれの中身に違う内容を表示できるようにしていきます。
では今回作るもののデモと仕様を確認しましょう!
デモ
ページを下へスクロールすると右下にボタンが表示されます。クリックするとページの最上部へと移動します。
仕様
以下の仕様をもとに実装を進めていきます。
ボタンをクリックでそれぞれのモーダルを表示する
×アイコンまたは背景をクリックでモーダルを閉じる
“ふわっ”と表示されるフェードインアニメーションをつける
今回もcss、jsファイルは外部ファイルとしてhtmlで読み込みます。
【実践】ページ内に複数のモーダルウィンドウを実装する
HTMLを準備する
モーダルの表示を制御するボタン、モーダル内部のコンテンツをHTMLに記載していきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1ページ内の複数モーダルウィンドウ サンプル</title>
<link rel="stylesheet" href="style.css">
<link href="https://use.fontawesome.com/releases/v6.7.2/css/all.css" rel="stylesheet">
</head>
<body>
<header>
<h1>作って学ぶWeb制作 中級</h1>
<h2>1ページ内に複数モーダルウィンドウを作ってみよう</h2>
</header>
<!-- start main contents -->
<main>
<button class="open-modal open-btn" data-modal="1">モーダル1</button>
<button class="open-modal open-btn" data-modal="2">モーダル2</button>
<!-- モーダル本体 -->
<div class="modal" id="modal-1">
<div class="modal-content">
<button class="close-btn" data-modal="1">
<i class="fa-solid fa-xmark" style="color: #5b370d;"></i>
</button>
<h2>これはモーダル1です</h2>
<p>モーダルの中身にそれぞれ違う内容が表示できます</p>
</div>
</div>
<div class="modal" id="modal-2">
<div class="modal-content">
<button class="close-btn" data-modal="2">
<i class="fa-solid fa-xmark" style="color: #5b370d;"></i>
</button>
<h2>これはモーダル2です</h2>
<p>複数のモーダルが実装できます!</p>
</div>
</div>
<!-- モーダル本体 -->
</main>
<!-- end main contents-->
<script type="text/javascript" src="script.js"></script>
</body>
</html>
ソースコード ポイント解説
<button class="open-modal open-btn" data-modal="1">モーダル1</button>
<button class="open-modal open-btn" data-modal="2">モーダル2</button>
モーダルを開くボタンにdata-modal属性をつけています。これがボタンとモーダルを紐付ける役割をしています。
CSSでスタイルを追加する
今回はモーダル表示時のCSSアニメーションがポイントになります!
* {
box-sizing: border-box;
}
body {
font-family: "Arial", sans-serif;
}
h1{
font-size: 24px;
}
h2{
font-size: 18px;
}
/* ボタン */
.open-btn {
background-color: #f7d96b;
color: #5b370d;
padding: 0.8rem 1.5rem;
font-size: 1.2rem;
font-weight: bold;
border: none;
border-radius: 10px;
cursor: pointer;
transition: background-color 0.3s ease;
margin: 16px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
.open-btn:hover {
background-color: #dfbb36;
}
.close-btn {
position: absolute;
top: 10px;
right: 15px;
font-size: 1.6rem;
background: transparent;
border: none;
cursor: pointer;
transition: transform 0.3s ease;
}
/* モーダル背景 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(79, 79, 79, 0.5);
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
/* モーダル表示状態 */
.modal.active {
display: flex;
opacity: 1;
pointer-events: auto;
}
/* モーダルの中身*/
.modal-content {
background: #fff;
padding: 1rem;
border-radius: 10px;
width: 80vw;
max-width: 500px;
text-align: center;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
position: relative;
opacity: 0;
transform: scale(0.8);
transition: all 0.3s ease;
}
/* アニメーション*/
.modal.active .modal-content {
animation: fadeInScale 0.4s ease forwards;
}
@keyframes fadeInScale {
0% {
opacity: 0;
transform: scale(0.8);
}
100% {
opacity: 1;
transform: scale(1);
}
}
ソースコード ポイント解説
@keyframes fadeInScale {
0% {
opacity: 0;
transform: scale(0.8);
}
100% {
opacity: 1;
transform: scale(1);
}
}
scaleを0.8→1にしてモーダルを小さめから通常の大きさへ拡大する動きを、opacityを0→1で透明から100%表示にすることで”ふわっ”と感を演出しています。
Javascriptで複数モーダルの表示制御をする
最後にモーダルの表示制御を実装していきましょう。関数で処理を分けることで、モーダルの数が増えた時にも対応できるようにします。
document.addEventListener('DOMContentLoaded', () => {
modalTriggers();
});
//モーダルを開く・閉じる・背景クリックのイベントをまとめて設定
function modalTriggers() {
const openButtons = document.querySelectorAll('.open-modal');
const closeButtons = document.querySelectorAll('.close-btn');
const modals = document.querySelectorAll('.modal');
openButtons.forEach(button => {
button.addEventListener('click', () => {
const modalId = button.dataset.modal;
openModal(modalId);
});
});
closeButtons.forEach(button => {
button.addEventListener('click', () => {
const modalId = button.dataset.modal;
closeModal(modalId);
});
});
//モーダルの背景クリックで閉じる
modals.forEach(modal => {
modal.addEventListener('click', e => {
if (e.target.classList.contains('modal')) {
modal.classList.remove('active');
}
});
});
}
//指定したIDのモーダルを開く関数
function openModal(modalId) {
const modal = document.getElementById(`modal-${modalId}`);
if (modal) {
modal.classList.add('active');
}
}
//指定したIDのモーダルを閉じる関数
function closeModal(modalId) {
const modal = document.getElementById(`modal-${modalId}`);
if (modal) {
modal.classList.remove('active');
}
}
ソースコード ポイント解説
開く処理、閉じる処理をそれぞれ説明していきます。
openButtons.forEach(button => {
button.addEventListener('click', () => {
const modalId = button.dataset.modal;
openModal(modalId);
});
});
では次に呼び出すopenModal()関数で何をしているかみていきましょう。
function openModal(modalId) {
const modal = document.getElementById(`modal-${modalId}`);
if (modal) {
modal.classList.add('active');
}
}
.activeクラスを追加してモーダルの要素を表示します。
closeButtons.forEach(button => {
button.addEventListener('click', () => {
const modalId = button.dataset.modal;
closeModal(modalId);
});
});
ここまでで解説してきた処理はmodalTriggers()としてまとめられています。
document.addEventListener('DOMContentLoaded', () => {
modalTriggers();
});
ページが完全に読み込まれた後に モーダルに対するイベントをすべてまとめているmodalTriggers()呼び出します。関数化することでモーダルの数を増やしたい場合にもHTMLの要素とCSSがあれば、同じ仕組みを再利用可能になります。

関数化するとコードも見やすくもなって、機能を追加したいときにもメンテしやすいですね
まとめ
今回の作って学ぶWeb制作中級編では1ページ内の複数モーダルウィンドウを実装してみました。複数モーダルを使うとページ遷移なしで詳細情報が表示できるため、ユーザーの離脱も防ぐ役割がありますね。ふわっとしたアニメーションも付けましたが、ちょっとした動きを加えることで、視覚的な効果もアップします!ユーザーのことを考えて細かい部分も工夫していきたいですね!
実装が参考になればうれしいです。お読みいただきありがとうございました。