バウンドしながら開閉するモーダルウインドウの作り方
バウンドしながら開閉するモーダルウインドウの作り方を紹介します。モーダルを開くときは少し弾むような動きで表示され、閉じるときも軽く反動を付けながら縮小して閉じるため、動きのある印象的なUIを簡単に実装できます。HTML・CSS・JavaScriptのみで作成しているので、ライブラリを使わずにそのまま導入できます。
サンプルコードでは、「モーダルを開く」ボタンをクリックするとバウンドアニメーション付きでモーダルが表示され、「閉じる」ボタンをクリックするとバウンドしながら閉じます。表示と非表示の両方にアニメーションを設定しているため、開閉動作全体に統一感があり、自然な演出になります。
お知らせや確認画面、キャンペーン表示など、ユーザーの目を引きたい場面で利用できます。ボタンの文字やモーダル内のタイトル・説明文はHTMLから変更でき、色・サイズ・角丸・影・アニメーション時間などはCSSで自由にカスタマイズできます。シンプルな構成なので、バウンドアニメーション付きモーダルのベースとしても活用しやすいサンプルです。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
バウンド開閉モーダル
モーダルを開くと弾むように表示され、閉じると反動を付けながら閉じます。
モーダルを開く
モーダルタイトル
バウンドアニメーションによる開閉動作を確認できます。
閉じる
「モーダルを開く」をクリックするとバウンドしながら表示され、「閉じる」をクリックするとバウンドしながら閉じます。
コードをコピーして使おう!
html
css
js
このタブをコピー
サンプル一式をダウンロード
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン表示対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>バウンドしながら開閉するモーダルウインドウ</title>
<!-- CSSファイルを読み込み -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- モーダル表示エリア -->
<div class="modal-open-close-bounce_wrap">
<!-- タイトル -->
<h1 class="modal-open-close-bounce_title">
バウンド開閉モーダル
</h1>
<!-- 説明文 -->
<p class="modal-open-close-bounce_text">
モーダルを開くと大きく弾みながら表示され、閉じると反動を付けながら閉じます。
</p>
<!-- モーダルを開くボタン -->
<button
class="modal-open-close-bounce_open"
type="button"
data-bounce-modal-open>
モーダルを開く
</button>
</div>
<!-- モーダル背景 -->
<div
class="modal-open-close-bounce_overlay"
data-bounce-modal-overlay>
<!-- モーダル本体 -->
<div
class="modal-open-close-bounce_modal"
role="dialog"
aria-modal="true"
aria-labelledby="bounce-modal-title"
data-bounce-modal>
<!-- モーダルタイトル -->
<h2
class="modal-open-close-bounce_modal-title"
id="bounce-modal-title">
モーダルタイトル
</h2>
<!-- モーダル本文 -->
<p class="modal-open-close-bounce_modal-text">
大きなバウンドアニメーションによる開閉動作を確認できます。
</p>
<!-- モーダルを閉じるボタン -->
<button
class="modal-open-close-bounce_close"
type="button"
data-bounce-modal-close>
閉じる
</button>
</div>
</div>
<!-- JavaScriptファイルを読み込み -->
<script src="script.js"></script>
</body>
</html>
/* ページ全体 */
body{
margin:0; /* 外側の余白 */
padding:40px 20px; /* 内側の余白 */
background:#ffffff; /* 背景色 */
font-family:sans-serif; /* フォント */
}
/* モーダル表示エリア */
.modal-open-close-bounce_wrap{
max-width:700px; /* 最大横幅:変更すると表示エリアの幅が変わる */
margin:40px auto; /* 上下余白・中央配置 */
padding:32px; /* 内側余白 */
border:1px solid #e5e7eb; /* 枠線 */
border-radius:18px; /* 角丸 */
background:#f8fafc; /* 背景色 */
text-align:center; /* 中央揃え */
box-sizing:border-box; /* paddingを幅に含める */
}
/* タイトル */
.modal-open-close-bounce_title{
margin:0 0 12px; /* 下余白 */
font-size:22px; /* 文字サイズ */
font-weight:700; /* 太字 */
}
/* 説明文 */
.modal-open-close-bounce_text{
margin:0 0 24px; /* 下余白 */
color:#4b5563; /* 文字色 */
line-height:1.8; /* 行間:値を大きくすると行間が広がる */
}
/* 開くボタン・閉じるボタン */
.modal-open-close-bounce_open,
.modal-open-close-bounce_close{
padding:10px 22px; /* 内側余白 */
border:none; /* 枠線なし */
border-radius:8px; /* 角丸 */
color:#ffffff; /* 文字色 */
font-size:16px; /* 文字サイズ */
font-weight:700; /* 太字 */
cursor:pointer; /* マウスカーソル */
}
/* モーダルを開くボタン */
.modal-open-close-bounce_open{
background:#2563eb; /* 背景色 */
}
/* モーダルを閉じるボタン */
.modal-open-close-bounce_close{
background:#111827; /* 背景色 */
}
/* モーダル背景 */
.modal-open-close-bounce_overlay{
display:none; /* 初期状態は非表示 */
position:fixed; /* 画面全体へ固定 */
inset:0; /* 画面全体に広げる */
z-index:9999; /* 最前面に表示 */
align-items:center; /* 縦中央 */
justify-content:center; /* 横中央 */
padding:20px; /* 画面端との余白 */
background:rgba(15,23,42,.55); /* 背景の暗さ:最後の数値を大きくすると濃くなる */
box-sizing:border-box; /* paddingを幅に含める */
}
/* モーダル表示時 */
.modal-open-close-bounce_overlay.is-active{
display:flex; /* モーダル背景を表示 */
}
/* モーダル本体 */
.modal-open-close-bounce_modal{
width:100%; /* 横幅 */
max-width:420px; /* 最大横幅:変更するとモーダルの幅が変わる */
padding:28px; /* 内側余白 */
border-radius:18px; /* 角丸 */
background:#ffffff; /* 背景色 */
box-shadow:0 20px 40px rgba(0,0,0,.2); /* 影 */
box-sizing:border-box; /* paddingを幅に含める */
animation:modal-open-close-bounce_open .45s ease forwards; /* .45秒で開く:値を大きくすると遅く、小さくすると速くなる */
}
/* モーダルを閉じる時 */
.modal-open-close-bounce_modal.is-closing{
animation:modal-open-close-bounce_close .45s ease forwards; /* .45秒で閉じる:JavaScriptの450ミリ秒と合わせる */
}
/* モーダルタイトル */
.modal-open-close-bounce_modal-title{
margin:0 0 12px; /* 下余白 */
font-size:22px; /* 文字サイズ */
font-weight:700; /* 太字 */
}
/* モーダル本文 */
.modal-open-close-bounce_modal-text{
margin:0 0 24px; /* 下余白 */
color:#4b5563; /* 文字色 */
line-height:1.8; /* 行間:値を大きくすると行間が広がる */
}
/* 開く時のバウンドアニメーション */
@keyframes modal-open-close-bounce_open{
0%{
opacity:0; /* 透明な状態から開始 */
transform:scale(.65); /* .65倍から開始:小さくするとバウンドが大きく見える */
}
55%{
opacity:1; /* 表示状態 */
transform:scale(1.22); /* 1.22倍まで拡大:大きくすると強く跳ねる */
}
75%{
transform:scale(.9); /* .9倍まで縮小:小さくすると反動が大きくなる */
}
90%{
transform:scale(1.08); /* 1.08倍まで再拡大:大きくすると2回目の弾みが強くなる */
}
100%{
opacity:1; /* 完全に表示 */
transform:scale(1); /* 通常サイズ */
}
}
/* 閉じる時のバウンドアニメーション */
@keyframes modal-open-close-bounce_close{
0%{
opacity:1; /* 表示状態から開始 */
transform:scale(1); /* 通常サイズ */
}
25%{
transform:scale(1.18); /* 1.18倍まで拡大:大きくすると閉じる前の反動が強くなる */
}
45%{
transform:scale(.9); /* .9倍まで縮小:小さくすると閉じる途中の弾みが大きくなる */
}
100%{
opacity:0; /* 透明にする */
transform:scale(.6); /* .6倍まで縮小:小さくするとより小さく閉じる */
}
}
/* 画面幅640px以下 */
@media (max-width:640px){
/* モーダル表示エリア */
.modal-open-close-bounce_wrap{
padding:24px 18px; /* 狭い画面用の内側余白 */
}
}
// モーダルを開くボタンを取得
const bounceModalOpen=document.querySelector("[data-bounce-modal-open]");
// モーダルを閉じるボタンを取得
const bounceModalClose=document.querySelector("[data-bounce-modal-close]");
// モーダル背景を取得
const bounceModalOverlay=document.querySelector("[data-bounce-modal-overlay]");
// モーダル本体を取得
const bounceModal=document.querySelector("[data-bounce-modal]");
// 開くボタンをクリックした時
bounceModalOpen.addEventListener("click",function(){
// 閉じるアニメーション用クラスを外す
bounceModal.classList.remove("is-closing");
// モーダルを表示
bounceModalOverlay.classList.add("is-active");
});
// 閉じるボタンをクリックした時
bounceModalClose.addEventListener("click",function(){
// 閉じるバウンドアニメーション用クラスを付ける
bounceModal.classList.add("is-closing");
// 450ミリ秒後に非表示:CSSの .45秒と合わせる
setTimeout(function(){
// モーダル背景を非表示
bounceModalOverlay.classList.remove("is-active");
// 次回表示用にクラスを外す
bounceModal.classList.remove("is-closing");
},450);
});
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLでモーダルウインドウの構造を作成し、CSSでズームイン・ズームアウトの開閉アニメーションやデザインを設定、JavaScriptでモーダルの表示・非表示を制御しています。
モーダルを開くと拡大しながら表示され、閉じると縮小しながら自然に消えるアニメーションを実装しています。HTML・CSS・JavaScriptを役割ごとに分けているため、見た目や動作を個別に編集しやすく、アニメーション付きモーダルの基本構成を学びたい方にも利用しやすいサンプルです。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
・index.html:モーダル本体、タイトル、説明文、開くボタン、閉じるボタンなど画面に表示する内容を記述します。
・style.css:画面レイアウト、ボタン、モーダルのデザイン、背景オーバーレイ、ズームイン・ズームアウトの開閉アニメーションを設定します。
・script.js:開くボタン・閉じるボタンのクリックイベントを処理し、モーダルの表示・非表示と閉じるアニメーション終了後の非表示処理を行います。
設置方法・使い方
① sampleフォルダを作成します。
② index.html・style.css・script.jsの3ファイルを配置します。
③ sample/index.htmlをブラウザで開きます。
④ 「モーダルを開く」をクリックするとズームインで表示され、「閉じる」をクリックするとズームアウトしながら閉じる動作を確認できます。
カスタマイズできる内容
・index.htmlでは、ボタンの文字、モーダルタイトル、説明文を自由に変更できます。
・style.cssでは、モーダルの幅、背景色、文字色、余白、角丸、影、ボタンデザインなどを変更できます。
・style.cssでは、ズームイン・ズームアウトのアニメーション内容を変更して好みの動きへ調整できます。
・script.jsでは、モーダルを開く・閉じる処理やイベントを追加できます。
数値調整
・style.cssの「animation: ~ .4s」は開閉アニメーション時間です。値を大きくするとゆっくり、小さくすると素早く動作します。
・style.cssの「transform:scale(0.8);」などのscale値を変更すると、拡大・縮小の大きさを調整できます。
・script.jsの「setTimeout(…,400);」の400はミリ秒です。CSSのアニメーション時間と同じ値に設定すると自然に閉じます。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssで「width:100%;」「max-width」「padding」などを設定しているため、画面サイズに合わせてモーダルの幅や余白が自動調整されます。スマートフォン・タブレット・PCでもレイアウトを崩さず利用できます。
コメント