モーダルウィンドウの背景はこれで固定できます!

目次

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

対応する機会が多い仕様ではないですが、忘れたころにやってくるこのお願い。

「昔やった気がするけど、ちょっとややこしかったような…」

と不安になる方も多いはず。
これ、CSSだけで対応しようとすると失敗するんです。

しかしポイントさえ押さえてしまえば、割と簡単に対処できます。
急な依頼でも慌てることがないように、解決法を見ていきましょう。

【基本コード】モーダルの背景を固定しよう

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はデザインに合わせて調整してください。

【Demo】モーダルの背景を固定しよう

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

【Point】モーダルの背景を固定しよう

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

【解説】モーダルの背景を固定しよう

細かくコードを見ていきましょう。

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

スクロール量を取得

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

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

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

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

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

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

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

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

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

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

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

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

ポイントは、

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

です。

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

最後に、「モーダルを閉じるボタン」やオーバーレイをクリックした時に固定を解除する処理を実装します。

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

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

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

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

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

【まとめ】モーダルの背景を固定しよう

昔私が失敗した原因は、取得したスクロール量をCSSだけで制御しようとしたことです。

大切なのは、

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

すること!!

以上です。
少しでもお役に立てたら幸いです。

参考サイト

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

Share

Comments

コメントを残す

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

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

CAPTCHA