▲TOPへ戻る

background-attachment: fixedを使わず、javascriptでパララックスを表現

以下のようなパララックスをjavascriptで作ってみました。

background-attachment: fixed;を使えば、CSSだけで作れるのですが、 safariやスマホでうまく動いてくれないので。

parallax

HTML

sectionタグが1セットです。あと、好きなだけsectionを追加できます。

HTML
  <section>  <!-- 1セット -->
    <div class="parallax bgI1">1</div>  <!-- background-imageで画像を指定 -->
    <p>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam,quaerat fuga, accusantium eveniet tempore molestias provident solutalibero minima similique earum reiciendis blanditiis cum quod ipsum quiaitaque unde cumque?
    </p>
  </section>

  <section>  <!-- 1セット -->
    <div class="parallax bgI2">2</div>  <!-- background-imageで画像を指定 -->
    <p>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam,quaerat fuga, accusantium eveniet tempore molestias provident solutalibero minima similique earum reiciendis blanditiis cum quod ipsum quiaitaque unde cumque?
    </p>        
  </section>

CSS

CSS
   section {
    position: relative;
    min-height: 100vh;  /* 高さは最低でも画面の高さ分あるように */
    padding: 10px 0;
  }
  .parallax {
    position: absolute;  /* sectionのtop:0に配置 */
    top: 0;
    display: none;  /* 最初は非表示 */
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    width: 100%;
    height: 100vh;
    font-size: 3em;
    color: #fff;
    z-index: -1;
  }
  .bgI1 {
    background-image: url("https://gxy-life.com/images/blog/202202/3 (3).JPG");
  }
  .bgI2 {
    background-image: url("https://gxy-life.com/images/blog/202202/4 (22).JPG");
  }
  .bgI3 {
    background-image: url("https://gxy-life.com/images/blog/202202/5 (6).JPG");
  }
  .bgI4 {
    background-image: url("https://gxy-life.com/images/blog/202202/7.JPG");
  }
  .bgI5 {
    background-image: url("https://gxy-life.com/images/blog/202202/9 (2).JPG");
  }
  .parallax.active {  /* activeが追加されたらfixedに */
    position: fixed;
    top: 0;
  }
  .p {
    max-width: 800px;
    margin: 50px auto;
    padding: 50px;
    font-size: 1.5em;
    color: #fff;
  }

javascript

全部で21行。そんなに複雑ではないですね。

最初にsectionと画像表示部分を取得

  const parallax = document.querySelectorAll(".parallax");
  const section = document.querySelectorAll("section");

最初のsection内の画像は表示させる。

  parallax[0].style = "display: block;";

スクロールイベントで処理

  document.addEventListener("scroll", function () {
    for (let i = 0; i < section.length; i++) {
      // section上辺の画面上から距離
      const getElementDistanceTop = section[i].getBoundingClientRect().top;
      // section下辺の画面上から距離
      const getElementDistanceBottom =
        section[i].getBoundingClientRect().bottom;

      // sectionの上辺が画面下に現れたら、非表示にしていた画像を表示
      if (getElementDistanceTop < window.innerHeight) {
        parallax[i].style.display = "block";
      }
      // sectionの上辺が画面上に消えてから、section下辺が画面上に消えるまで
      if (getElementDistanceTop < 0 && getElementDistanceBottom > 0) {
        parallax[i].classList.add("active");
      } else {  // それ以外はactiveを削除
        parallax[i].classList.remove("active");
      }
    }
  });

参考

css
【CSS】positionとは?relativeとabsoluteの違い。初心者向け
js
要素の高さを取得する方法。getBoundingClientRectとは?window.innerHeightとは?window.pageYOffsetとは?
js
要素を取得し、classを追加、削除、切り替える方法

デモページはこちらから↓

こんな記事も読まれています。

profile

パソコン好きなガオ

コロナ禍によるステイホームを機にプログラミングを学ぶ。パソコンに関してはプロではないが、ちょっと詳しい程度。

パソコン

javascript

カメラ

ブログ