スクロールに連動して背景画像が切り替わる効果の実装方法【jQuery+レスポンシブ】

スクロールに連動して任意のセクションが表示されると背景画像が切り替わる効果をjQueryとCSSで実装しました。

公開・配布されているjQueryプラグインなどは未使用です。
そのセクションに合った背景画像をフェードイン・アウトで表示させたかったので備忘録としてデモを制作しアップしています。

demoページを見る

フェードイン効果はCSSを使う

CSS3のプロパティtransitionを使い、フェードイン・アウトを表現します。

背景自体はposition: fixedで配置し、デフォルトではopacity: 0で透明にしておきます。
コンテンツが表示されるタイミングでclass=showを追加し、opacity: 1に変更。

背景にする画像はbackground-imageであらかじめ読み込んでおきます。

/* init */
.background {
    top: 0;
    left: 0;
    right: 0;
    height: 100%;
    position: fixed;
    background-position: center center;
    opacity: 0;
-webkit-background-size: cover;
        background-size: cover;
-webkit-transition: all 0.5s ease 0s;
   -moz-transition: all 0.5s ease 0s;
        transition: all 0.5s ease 0s;
}
.show .background {
    opacity: 1;
}
.contents .wrap {
    padding: 40vh 0 60vh;
    position: relative;
    z-index: 2;
}
/* design*/
#content01_bg {background-image: url(images/bald-eagle-2715461_1920.jpg);}
#content02_bg {background-image: url(images/coast-2723729_1920.jpg);}
#content03_bg {background-image: url(images/woman-2711279_1920.jpg);}
#content01 .wrap { background-color: rgba(255,0,0,0.2);}
#content02 .wrap { background-color: rgba(0,255,0,0.2);}
#content03 .wrap { background-color: rgba(0,0,255,0.2);}
.text-box {
    padding: 50px 25px;
    width: 480px;
    background-color: rgba(0,0,0,0.5);
    color: #fff;
}
.text-box .catch {
    margin: 0 0 10px;
    font-size: 40px;
}
.text-box .copy {
    margin: 0;
    line-height: 2;
}

jQueryのscrollイベントでclassを操作

div.contentsに、class=showをaddClass, removeClassすることにより、背景画像がふわっとフェードインします。

$(function(){
    $(window).on('load scroll resize', function(){
        var winHeight = $(window).height();
        var scrollTop = $(window).scrollTop();
        var showClass = 'show';
        var timing = 100;
        $('.contents').each(function(i, elem){
            var contentsPOS = $(elem).offset().top;
            if (scrollTop >= contentsPOS - winHeight + timing){
              $(elem).addClass(showClass);
            } else {
              $(elem).removeClass(showClass);
            }
        });
    });
});

【追記:2024.2.28】コードを一部修正しました。

コピペでも動作します。
jQuery本体の読み込みも忘れずにしておきましょう。

いくつでも設置可能です

div.contentsdiv.backgroundの要素は必須で、あとは自由にカスタマイズ可能。

div.backgroundの中身は空です。

div.contentsをいくつ増やしても同じようにフェードイン・アウトします。

<section id="contents">
    <div id="content01" class="contents">
        <div id="content01_bg" class="background"></div>
        <div class="wrap">
            <div class="text-box">
                <p class="catch">コンテンツ1</p>
                <p class="copy">テキスト</p>
            </div>
        </div>
    </div><!-- content01 -->
    <div id="content02" class="contents">
        <div id="content02_bg" class="background"></div>
        <div class="wrap">
            <div class="text-box">
                <p class="catch">コンテンツ2</p>
                <p class="copy">テキスト</p>
            </div>
        </div>
    </div><!-- content02 -->
    <div id="content03" class="contents">
        <div id="content03_bg" class="background"></div>
        <div class="wrap">
            <div class="text-box">
                <p class="catch">コンテンツ3</p>
                <p class="copy">テキスト</p>
            </div>
        </div>
    </div><!-- content03 -->
</section>

以上、「jQueryとCSSで背景画像のフェード切り替え効果」の実装方法でした。

簡単なのでシンプルなランディングページなどに活用してみてはいかがでしょうか。

この記事へのコメント
  1. ちい より:

    はじめまして。
    記事内容を参考に作成してみているのですが、div.contentsを5つに増やしcontent04_bg, content05_bgと複製するとcontent03_bgと同時に04,05もshowクラスが付与されてしまいます。

    04,05のコンテンツが極端に短いということはなく…jQueryでも特に枚数の指定などをしれいるわけでもないので原因がわからないのですがご教示いただけないでしょうか。

    • ナオユ より:

      コメントありがとうございます。
      確かに5個目のcontentあたりから想定していないタイミングでshowクラスを付与していました。
      javascriptコードを見直し修正しましたので、こちらでいかがでしょう?

      $(function(){
          $(window).on('load scroll resize', function(){
              var winHeight = $(window).height();
              var scrollTop = $(window).scrollTop();
              var showClass = 'show';
              var timing = 100;
              $('.contents').each(function(i, elem){
                  var contentsPOS = $(elem).offset().top;
                  if (scrollTop >= contentsPOS - winHeight + timing){
                    $(elem).addClass(showClass);
                  } else {
                    $(elem).removeClass(showClass);
                  }
              });
          });
      });
    • ちい より:

      ナオユさん

      ご丁寧にありがとうございます!無事動きました!
      いただいたコードは記事のものと何が違っているのか、自分でも勉強してみます。ありがとうございました。

  2. ファルコン より:

    初めまして。こちらのサイト参考にさせて頂き、自社HP制作に取り組んでおります。
    ページ最後になりましたら、背景をなしにしてフッターを表示させたい場合はどのようにしたら良いでしょうか。

    • ナオユ より:

      最後のコンテンツ、例えば#content04_bgを作るとして、CSSでbackground:#fffにすると白背景になります(背景色はファルコン様のサイトに合わせて頂ければ)。
      この方法だといかがでしょうか。

  3. すな より:

    初めまして。こちらのサイトを参考にアルバムのようなサイトを作成させていただきました。
    理想のサイトができ上がりそうで、大変感謝しております。
    さて、私が作りましたこのアルバムのようなサイトは、写真のフォルダ分けを、変わる背景で表しています。
    しかし、サーバーに上げると背景が違うところで変わってしまいます。
    手動で再読み込みすると正常に動くのですが。。。
    再読み込みするコードを書いたり、画像が多いからhtmlの読み込みの問題かとローディング画面をつけたりしたのですが、
    再読込しない、開いただけだとどうしてもずれてしまいます。
    ちなみに背景は3度変わり、1個目の背景は写真8枚目までで、写真9枚目から14枚目で2個目の背景に変わり、最後の背景は4枚の写真を設定しております。
    画像は大分圧縮していますが数が多いのも問題なのでしょうか。他にこのような事例は上がっていませんか?私だけでしょうか。
    私にはもうお手上げ状態ですので、何か解決策をご存じでしたら教えていただきたいです。よろしくお願いいたします。

    • ナオユ より:

      恐らくですが…
      初回ロード時、画像の遅延読み込みや追加挿入されるタグなどによって.contentsの位置がずれるからかも知れません。
      JSの1行目を下記のようにして、ページ全体の読み込み後に動くようにしてみてください。

      $(window).on(‘load’, function(){

  4. ガンモ より:

    ナオユ様
    お礼が遅れてしまいましたが、ご返信ありがとうございます。
    やはり難しそうですね、、、
    ブラウザの仕様と割り切ることにします。
    ありがとうございました。

  5. ガンモ より:

    初めまして。
    こちらの記事を参考にさせて頂き、
    wordpressで作成したWEBサイトの背景を切り替えることができました。
    ありがとうございます。

    一点だけ質問させてください。
    iphoneのsafariで作成したサイトを見た際
    下部のツールバーが表示された状態で上にスクロールすると
    一瞬、ツールバーの裏部分の背景画像が消えた状態になります。
    間を置いてすぐに表示されるのですが気になってしまいます。

    自分なりにいろいろと試行錯誤したのですが、
    解決できず困っているので、もし解決方法をご存じでしたら
    教えて頂けないでしょうか?

    お手数をお掛けしますが、よろしくお願い致します。

    • ナオユ より:

      下のツールバーが表示している時は、ブラウザの高さはツールバー上端までです。
      ツールバーの下には背景画像は敷かれません。
      上にスクロールした時にツールバーが隠れるので、その高さ分だけ背景が拡がります。
      背景の処理が一瞬遅れている、ということになる思います。
      ブラウザの仕様なので、解決は厳しいかもしれません。すみません。

コメントを残す

メールアドレスが公開されることはありません。

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

このサイトの管理者

ナオユ

Wordpress初心者向けにカスタマイズ方法やWEB制作のノウハウをポロッとまとめています。広告代理店→WEB制作会社→リモート勤務になり在宅ワークしながらアフィリエイトなど副業に挑戦中|子ども大好き新米パパ@H29男児|フラット35で実家を建て直し親と同居|仮想通貨投資(絶賛含み損w)