jQueryでレスポンシブ対応のシンプルなモーダルウィンドウ【コピペOK】

画像をクリックすると
画面中央に拡大表示する
シンプルなモーダルウィンドウのサンプルです。

ソースコードと解説


<div class="bl_galleryImgBlock">
  <div class="bl_galleryImgBlock_wrapper">
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
    <div class="bl_galleryImgBlock_item js_modalButton" style="background-image:url([サムネイルの画像URL]);" data-src="[拡大表示させたい画像URL]"></div>
  </div>
</div>

<div class="bl_modalBlock">
  <div class="bl_modalBlock_wrapper">
    <div class="bl_modalBlock_closeButton"></div>
  </div>
</div>

[サムネイルの画像URL]と
[拡大表示させたい画像URL]に
それぞれ任意のURLを代入してください。

.bl_modalBlockは
拡大画像を表示する領域になります。


/*ギャラリー部分レイアウト*/

.bl_galleryImgBlock_wrapper {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  margin-bottom: 45px; }
  @media screen and (max-width: 840px) {
    .bl_galleryImgBlock_wrapper {
      margin-bottom: 30px; } }

.bl_galleryImgBlock_item {
  width: calc((100% - 10px) / 3);
  margin-right: 5px;
  margin-bottom: 5px;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  cursor: pointer; }
  .bl_galleryImgBlock_item:nth-child(3n) {
    margin-right: 0; }
  .bl_galleryImgBlock_item:before {
    content: "";
    display: block;
    padding-top: 100%; }

/*モーダル*/
.bl_modalBlock {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.8);
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  z-index: 100; }
  .js_openModal .bl_modalBlock {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex; }

.bl_modalBlock_wrapper {
  position: relative;
  width: 80vh;
  height: 80vh;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center; }
  @media screen and (max-width: 840px) {
    .bl_modalBlock_wrapper {
      width: 90%;
      max-width: 480px;
      height: auto; }
      .bl_modalBlock_wrapper:before {
        content: "";
        display: block;
        padding-top: 100%; } }

.bl_modalBlock_closeButton {
  position: absolute;
  right: 0;
  top: -10px;
  width: 20px;
  height: 20px;
  -webkit-transform: translateY(-100%);
  -ms-transform: translateY(-100%);
  transform: translateY(-100%);
  cursor: pointer; }
  .bl_modalBlock_closeButton:after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 149%;
    height: 2px;
    background-color: #ccc;
    -webkit-transform-origin: top left;
    -ms-transform-origin: top left;
    transform-origin: top left;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg); }
  .bl_modalBlock_closeButton:before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 149%;
    height: 2px;
    background-color: #ccc;
    -webkit-transform-origin: top right;
    -ms-transform-origin: top right;
    transform-origin: top right;
    -webkit-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    transform: rotate(-45deg); }

/*スクロール禁止*/
.js_fixed {
  position: fixed;
  width: 100%;
  height: 100%; }

モーダルのサイズ感や
背景色を変更したい場合は
CSSを適宜変更してください。

また今回は
画像表示時のスクロール禁止処理まで
包括した内容となります。

//モーダル表示時のスクロール無効化処理

var scrollBlockerFlag;
var scrollpos;

function scrollBlocker(flag){
  if(flag){
    scrollpos = $(window).scrollTop();
    $('body').addClass('js_fixed').css({'top': -scrollpos});
    scrollBlockerFlag = true;
  } else {
    $('body').removeClass('js_fixed').css({'top': 0});
    window.scrollTo( 0 , scrollpos );
    scrollBlockerFlag = false;
  }
}

//Galleryのモーダル処理
$(function(){

  var focusFlag = false;

  $(document).on('click','.js_modalButton',function(){
    var imgurl = $(this).data('src');
    $('.bl_modalBlock_wrapper').css('background-image','url(' + imgurl + ')');
    $('body').addClass('js_openModal');
    scrollBlocker(true);
    setTimeout(function(){
      focusFlag = true;
    },200);
  });
  $(document).on('click','.js_modalButton_close',function(){
    $('body').removeClass('js_openModal');
    scrollBlocker(false);
    focusFlag = false;
  });

  $(document).on('click','.bl_modalBlock_closeButton',function(){
    $('body').removeClass('js_openModal');
    scrollBlocker(false);
    focusFlag = false;
  });

  //モーダル以外の部分がクリックされた場合にモーダルを閉じる処理
  $(document).on('click touchend', function(event) {
    if (!$(event.target).closest('.bl_modalBlock_wrapper').length && focusFlag) {
      focusFlag = false;
      scrollBlocker(false);
      $('body').removeClass('js_openModal');
    }
  });
});

javascriptで
やっていることは主に3つ。

1つめはbodyに
.js_openModalを付与/削除することで
モーダルの開閉処理を行っています。

2つめはクリックした
.js_modalButtonの
data属性を利用してURLを取得し、
モーダルの画像表示領域である
.bl_modalBlock_wrapperの
background-imageに指定しています。

最後に3つめは、
モーダル表示時に
スクロールを不可としています。

また、ちょっとした工夫として、
jQueryのclosestメソッドを利用して、
モーダル以外の部分がクリックされた際に
モーダルを閉じる処理
を実装しています。

便利なプラグインもあるけれど…

画像のモーダルといえば、
LightboxColorboxなどの
jQueryプラグインが有名ですが、
安易なプラグインの導入は
ページ読み込み速度や
メンテナンス性の低下につながります。

やはりスクラッチでできる分は、
スクラッチで行うのが一番ですね。