【コピペOK】モーダルウィンドウの背景をjQueryで簡単に固定する方法

目次

「モーダルを開いたときに背景を固定して!」

とお願いされて、ドキッ!とした経験がある方は多いのではないでしょうか?

この要望は対応する機会が少ないので、忘れがちです。
私も「昔やった気がするけど、ちょっとややこしかったような…」と焦った経験が何度もあります。

しかし、モーダルウィンドウの背景固定はポイントさえ押さえてしまえば簡単!

ポイントは、スクロール量をCSSとJavaScriptで操作するタイミングを押さえること!
CSSだけで対応しようとすると失敗してしまいます。

この記事を読めば、モーダルの背景を固定する方法を理解できます。
今後同じ依頼をされても、自信を持って対応できるようになりますよ!

コピペで利用できるコードも用意しているので、時間が無い方はコードをコピペしてもらうだけでもOK!

ぜひコードだけでも見ていってくださいね!

【コピペコード】モーダルの背景を固定するためのコード

JavaScript

//変数の設定
var $body = $('body');

//スクロール量を保存
var scrollTop;

//スクロールを固定
function bodyFixedOn() {
  scrollTop = $(window).scrollTop();
  
  $body.css({
    position: 'fixed',
    top: -scrollTop
  });
}

//スクロールの固定を解除
function bodyFixedOff() {
  $body.css({
    position: '',
    top: ''
  });
  
  $(window).scrollTop(scrollTop);
}

//モーダルのトリガーをクリックしたとき
$('.modal-trigger').on('click', function() {
  bodyFixedOn();
});

//モーダルの閉じるボタンをクリックしたとき
$('.modal-close').on('click', function() {
  bodyFixedOff();
});

//モーダルのオーバーレイをクリックしたとき
$('.overlay').on('click', function() {
  bodyFixedOff();
});

HTML

<!-- モーダルを開くボタン -->
<a class="modal-trigger" href="#">
  モーダルを開く
</a>

<!-- モーダル本体 -->
<div class="modal-wrap">
    <div class="overlay"></div>
    <div class="modal-inner">
        <div class="img">
            モーダルが開きました。<br>背景も固定されました。
        </div>
        <button class="modal-close">×</button>
    </div>
    <!-- /.modal-inner -->
</div>
<!-- /.modal-wrap -->

SCSS

.modal-wrap{
  position: fixed;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100vh;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s linear, visibility .3s linear;
  z-index: -1;
  
  .overlay{
    position: fixed;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, .8);
    cursor: pointer;
  }
  
  .modal-inner{
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    background: rgba(255, 255, 255, .8);
    transform: translate(-50%, -50%);
    
    .modal-close{
      position: absolute;
      cursor: pointer;
    }
  }
  
  &.show{
    opacity: 1;
    visibility: visible;
    z-index: 10000;
  }
}

@media screen and (min-width: 768px) {
  .modal-trigger{
    transition: opacity .3s linear;
  }
  
  .modal-wrap{
    .modal-inner{
      max-width: 960px;
      
      .modal-close{
        top: -48px;
        right: 0;
      }
    }
  }
}

@media screen and (max-width: 767px) {
  .modal-wrap{
    .modal-inner{
      width: 90%;
      
      .modal-close{
        top: -30px;
        right: 0;
      }
    }
  }
}

こんなところでしょうか。
HTMLやCSSはデザインに合わせて調整してください。

【デモ】モーダルの背景を固定したサンプルページ

See the Pen bodyFIxed by Yusuke Saio (@saio-th) on CodePen.

モーダルの背景を固定する際に押さえるべきポイント

モーダルを開いたときに背景を固定するには、以下の3つのポイントを押さえましょう。

  • スクロール量を取得する
  • モーダルを開くときはスクロール量を「CSS」でbody要素に設定する
  • モーダルを閉じるときはスクロール量を「JavaScript」でwindowオブジェクトに設定する

この順にjQueryでコードを書くと、背景を固定するモーダルウィンドウを作成できます。

【解説】モーダルの背景を固定するコードを細かくチェック

それでは、細かくコードを見ていきますね。

詳細に説明するために、一部上記で紹介したものと異なるコードが出てきます。
実際に使用するときは「コピペコード」を参考にしてください

1. スクロール量を取得

スクロールの固定は「スクロール量」を指定したり解除したりすることで実現します。

そこで、まずはスクロール量を取得します。
スクロール量は$(window).scrollTop()メソッドで取得できます。

「モーダルウィンドウを開く」ボタンをクリックしたときに取得してください。

//例
$('.modal-trigger').on('click', function() {
  scrollTop = $(window).scrollTop();
});

2. モーダルが開いたらbody要素を固定して、CSSでスクロール量を設定する

次に、スクロールを固定する処理を実装します。
具体的には以下の処理をほどこします。

  • body要素をposition: fixed;で固定する
  • body要素の位置を、スクロール量分上にずらす

こうすることで、モーダルを開く前後で背景がズレません。

//例
$('.modal-trigger').on('click', function() {
  scrollTop = $(window).scrollTop(); //ウィンドウのスクロール量を取得
  
  $('body').css({
    position: 'fixed',
    top: -scrollTop //bodyタグのtopプロパティに、取得したスクロール量をマイナスの値で指定
  });
});

topプロパティにスクロール量を指定しないとどうなるでしょうか?
モーダルを開いた瞬間に背景がページの一番上に戻ってしまいます。

以下に図を用意したのでご覧ください。

図で説明した原理でスクロールが固定されます。

ポイントは、

モーダルを開いた時に、CSSでスクロール量を指定する

です。

3. モーダルを閉じたらbody要素の固定を解除して、windowオブジェクトにスクロール量を設定する

最後に「モーダルを閉じるボタン」や「オーバーレイ」をクリックした時に固定を解除する処理を実装します。
実装するコードは以下のとおり。

  • body要素に指定したCSSを解除する
  • windowオブジェクトにモーダルを開いた時に取得したスクロール量を指定する

これでモーダルを開く前の状態に戻すことができます。

//例
$('.modal-close').on('click', function() {
  $('body').css({
    position: '',
    top: ''
  });
  
  $(window).scrollTop(scrollTop);
});

bodyタグの固定を解除して、windowオブジェクトにモーダルを開く前のスクロール量を設定することで、元の状態に戻せます。

上記コードの通り、windowオブジェクトにスクロール量を設定するのにも、scrollTop()メソッドを使用します。
scrollTop()メソッドの引数に数値を入れるとスクロール量を指定することができますので、覚えておきましょう!

以上で一連の流れが完了です。

【まとめ】CSSとJavaScriptの使いどころを押さえてモーダルの背景を固定しよう!

この記事では、モーダルを開いたときに背景を固定するためのコードを解説しました。
やることは単純で、scrollTop()メソッドで取得したスクロール量をつけたり外したりするだけです。
ただし大切なのは、

開くときは、スクロール量をCSSで指定
閉じるときは、スクロール量をJavaScriptで指定

すること!

このポイントさえ押さえておけば、簡単に背景を固定したモーダルウィンドウを実装できます!
ぜひ参考にしてみてください!

参考サイト

■モーダルを開いている時にページがスクロールしてしまうのを防ぐCSSとJavaScriptのテクニック
https://coliss.com/articles/build-websites/operation/javascript/prevent-page-scrolling-when-a-modal-is-open.html

Share

Comments

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。

CAPTCHA