画像クリックで拡大表示(モーダル)の実装解説|Modal Image JS & CSS Guide

拡大表示(モーダル) デザイン見本

画像をクリックして画面中央に拡大表示するモーダルウィンドウの実装デモです。基本的なモーダル表示フェードインアニメーション複数画像への一括設定 の3パターンを収録。コピーしてすぐに使えるHTML・CSS・JSのコードを掲載しています。

① 基本的な画像モーダル — position: fixed で全画面表示、.open クラスで表示切替

サムネイルをクリックすると拡大表示されます(もう一度クリックで閉じます)

Click
Click to Close
HTML
<img src="photo.jpg" class="clickable-img" alt="">

<div class="img-modal">
  <img class="modal-photo" src="" alt="">
</div>
CSS
.clickable-img {
  cursor: zoom-in;
}

.img-modal {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.9);
  z-index: 9999;
  cursor: zoom-out;
  align-items: center;
  justify-content: center;
}

.img-modal.open {
  display: flex;
}

.modal-photo {
  max-width: 90%;
  max-height: 90vh;
  object-fit: contain;
}
JS
(function() {
  var thumb = document.querySelector('.clickable-img');
  var modal = document.querySelector('.img-modal');
  var photo = document.querySelector('.modal-photo');

  if (!thumb || !modal || !photo) return;

  document.body.appendChild(modal);

  thumb.addEventListener('click', function() {
    photo.src = thumb.src;
    modal.className = 'img-modal open';
  });

  modal.addEventListener('click', function() {
    modal.className = 'img-modal';
    photo.src = '';
  });
})();
position: fixed で画面全体を覆うオーバーレイを作り、.open クラスで display を切り替える

モーダルは最初 display: none で非表示にしておき、クリック時に display: flex へ切り替えます。position: fixed は本来ビューポート全体を基準に配置しますが、親要素に transformfilter が当たっていると基準がずれてしまいます。WordPress では テーマCSSがこれに該当することが多いため、document.body.appendChild(modal) でモーダルを <body> の直下に移動してから使うと確実です。z-index: 9999 を設定して他の要素の上に重ね、モーダルをクリックすると .open クラスが外れて非表示に戻ります。

② フェードインアニメーション — @keyframes でモーダル表示時にフワッと現れる

animation-duration: 0.5s

Click
Click to Close
HTML
<img src="photo.jpg" class="clickable-img" alt="">

<div class="img-modal">
  <img class="modal-photo" src="" alt="">
</div>
CSS
.clickable-img {
  cursor: zoom-in;
}

.img-modal {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.9);
  z-index: 9999;
  cursor: zoom-out;
  align-items: center;
  justify-content: center;
}

.img-modal.open {
  display: flex;
}

.modal-photo {
  max-width: 90%;
  max-height: 90vh;
  object-fit: contain;
}

@keyframes imgFadeIn {
  0%   { opacity: 0; transform: scale(0.9); }
  100% { opacity: 1; transform: scale(1);   }
}

.img-modal.open .modal-photo {
  animation: imgFadeIn 0.5s ease;
}
JS
(function() {
  var thumb = document.querySelector('.clickable-img');
  var modal = document.querySelector('.img-modal');
  var photo = document.querySelector('.modal-photo');

  if (!thumb || !modal || !photo) return;

  document.body.appendChild(modal);

  thumb.addEventListener('click', function() {
    photo.src = thumb.src;
    modal.className = 'img-modal open';
  });

  modal.addEventListener('click', function() {
    modal.className = 'img-modal';
    photo.src = '';
  });
})();
@keyframes でアニメーション名を定義し、.open クラスの CSS に animation プロパティで適用する

@keyframes はアニメーションの開始・終了状態を定義するCSSルールです。0% で透明かつ少し縮んだ状態、100% で通常の表示状態を指定することで「フワッと現れる」表現ができます。animation プロパティには「アニメーション名 継続時間 イージング」の順で記述します。ease を指定するとゆっくり始まり途中で速くなり最後にゆっくり終わる自然な動きになります。JSのコードは①と変わらず、CSS の追加だけでアニメーションが有効になります。

③ 複数画像への一括設定 — querySelectorAll と forEach で全画像に同じ動作を登録

いずれかのサムネイルをクリックすると拡大表示されます

Photo 1
Photo 2
Photo 3
Click to Close
HTML
<img src="photo1.jpg" class="clickable-img" alt="">
<img src="photo2.jpg" class="clickable-img" alt="">
<img src="photo3.jpg" class="clickable-img" alt="">

<div class="img-modal">
  <img class="modal-photo" src="" alt="">
</div>
CSS
.clickable-img {
  cursor: zoom-in;
}

.img-modal {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.9);
  z-index: 9999;
  cursor: zoom-out;
  align-items: center;
  justify-content: center;
}

.img-modal.open {
  display: flex;
}

.modal-photo {
  max-width: 90%;
  max-height: 90vh;
  object-fit: contain;
}
JS
(function() {
  var thumbs = document.querySelectorAll('.clickable-img');
  var modal = document.querySelector('.img-modal');
  var photo = document.querySelector('.modal-photo');

  if (!modal || !photo) return;

  document.body.appendChild(modal);

  thumbs.forEach(function(thumb) {
    thumb.addEventListener('click', function() {
      photo.src = thumb.src;
      modal.className = 'img-modal open';
    });
  });

  modal.addEventListener('click', function() {
    modal.className = 'img-modal';
    photo.src = '';
  });
})();
querySelectorAll でまとめて取得し、forEach でクリックイベントを一括登録する

querySelectorAll('.clickable-img') は同じクラスを持つ全要素をまとめて取得します。取得した要素群に対して forEach でループすることで、1つずつ個別に addEventListener を呼ぶ必要がなく、コードをシンプルに保てます。クリックされた要素(thumb)の src を共通のモーダル画像要素に転写することで、1つのモーダル構造を複数の画像で共有できます。HTMLに class="clickable-img" を持つ <img> を追加するだけで自動的に対応でき、JSのコードは変更不要です。


当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次