【CSS/jQuery】スクロールしたら下からふわっと要素を表示させる

HTML/CSS

今日は、お仕事で出てきた「スクロールしたら下からふわっと要素を表示させる」方法を備忘録としてまとめます。

こんにちは。Webコーダーのharuです。

*わたしについて*
3歳1歳の育児をしながら、5~7時・21~0時にプログラミングを独学しています。
2020.5.11~学習スタート
2020.8.10~実務でコーディングしています
HTML/CSS(SCSS)/jQuery/WordPress。
これからもっと知識をつけていきたく、インプット・アウトプットを続けています。

普段から学習していてわかったことや、気付きをログに残しています。
※認識の間違っている箇所があれば、ご教授いただけるとうれしいです!

【CSS/jQuery】スクロールしたら下からふわっと要素を表示させる

以前に実装したときは「scrollreveal.js」というプラグインを使用したのですが、今回はCSSでアニメーションをつけて、トリガー(クラスのつけ外し)にjQueryを使う方法で実装したので備忘録としてまとめます。

トリガーのjQueryは、一緒にお仕事させていただいた株式会社Ficusの社長さん(@ficus_at_osaka)に教えていただいたコードです。感謝…!とても使いやすいので、これから多用させていただきます✨

アニメーションのデモ

デザイン性がなさすぎて泣けますが、2種類のデモを作りました。笑

デモ1:要素をまとめてふわっとさせる

6つのnewsカード全てが一度にふわっとします。

デモ2:パーツを1つずつふわっとさせる

newsカードが一つずつふわっとします。

要素をまとめてふわっとさせる作り方

まず、コンポーネントまとめてふわっとさせる作り方です。

【HTML】

<!DOCTYPE html>
<html lang="jn">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>下からふわっと要素を表示【まとめてふわっとver.】</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <main>
      <p class="comment">スクロールしてください↓</p>
      <section class="news">
        <h1 class="news__title">news一覧</h1>
        <div class="news__outer">
          <ul class="news__items effect offs">
            <li class="news__item"></li>
            <li class="news__item"></li>
            <li class="news__item"></li>
            <li class="news__item"></li>
            <li class="news__item"></li>
            <li class="news__item"></li>
          </ul>
        </div>
      </section>
    </main>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>
・ふわっとさせたいコンポーネントの親(今回はul)にクラスを付ける
→クラスのつけ外しのため(offsクラス)
→アニメーションのため(effectクラス)
・css/js/jQuery読み込み必須

 

【jQuery】※クラスつけ外し
/*
スクロール出現
(「.offs」が付いた要素に対して、表示領域に入ったら「.ons」にクラスを変更する。)
・判定タイミング:対象がブラウザの下から 30%以上 入ったら実行、画面から出たら戻す
*/
// スクロール出現用関数(.offs ⇄ .ons)
function scr_ani(scr, offs_max) {
  var window_h = $(window).height(),
    offs_length = $(".offs").length,
    ons_length = $(".ons").length;
  if (offs_length) {
    var first_item = offs_max - offs_length;
    for (var i = 0; i < offs_length; i++) {
      var data_scr = first_item + i;
      var offs = $('.offs[data-scr="' + data_scr + '"]');
      var target = offs.offset().top;
      var trigger = target - (window_h + scr - window_h * 0.3);
      if (trigger < 0) {
        offs.removeClass("offs").addClass("ons");
      } else {
        break;
      }
    }
  }
  if (ons_length) {
    var last_item = ons_length - 1;
    for (var i = 0; i < ons_length; i++) {
      var data_scr = last_item - i;
      var ons = $('.ons[data-scr="' + data_scr + '"]');
      var target = ons.offset().top;
      var trigger = target - (window_h + scr);
      if (trigger > 0) {
        ons.removeClass("ons").addClass("offs");
      } else {
        break;
      }
    }
  }
}

$(function () {
  /*
  スクロール出現
  */
  var scr = $(window).scrollTop();
  // スクロール出現アイテムにナンバリング
  var offs_max = $(".offs").length;
  for (var i = 0; i < offs_max; i++) {
    $(".offs").eq(i).attr("data-scr", i);
  }

  scr_ani(scr, offs_max);

  /************
  スクロール時
  ************/
  $(window).on("scroll", function () {
    var scr = $(window).scrollTop();
    /*
    スクロール出現
    */
    scr_ani(scr, offs_max);
  }); // end scroll
}); // end function
・一緒にお仕事させていただいた株式会社Ficusの社長さん(@ficus_at_osaka)に教えていただいたコードです。感謝です。
・「offsクラス」がついている要素が、画面の下から30%に入ったら「ons」クラスに付け替える→今回のCSSアニメーションのトリガーに使います。このコードは編集必要なし。

【CSS】※アニメーション
/*ふわっと表示*/

.news__items.offs.effect {
  opacity: 0;
  transform: translate(0, 100px);
  -webkit-transform: translate(0, 100px);
}
.news__items.ons.effect {
  opacity: 1;
  -webkit-transform: translate(0, 0);
  transform: translate(0, 0);
  -webkit-transition: all 2s ease;
  transition: all 2s ease;;
}
・必要部分だけ抜粋しました。
アニメーション前(ulに.offsクラスがついているとき)
opacity:0; →非表示
transform: translate(0, 100px);→100px下の位置に設定
アニメーション後(ulに.onsクラスがついているとき)
opacity:1;→表示
transform: translate(0, 0);→デフォルトの位置に設定
transition: all 2s ease;→アニメーションにかかる時間を2秒に設定
transitionは.onsの方に書かないと、ふわっとしないので注意です!
コードとデモもう一度載せておきます↓

パーツを1つずつふわっとさせる

次にパーツを一つずつふわっとさせる方法です。

【HTML】

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>下からふわっと要素を表示【個別にふわっとver.】</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <main>
      <p class="comment">スクロールしてください↓</p>
      <section class="news">
        <h1 class="news__title">news一覧</h1>
        <div class="news__outer">
          <ul class="news__items offs">
            <li class="news__item effect delay-1"></li>
            <li class="news__item effect delay-2"></li>
            <li class="news__item effect delay-3"></li>
            <li class="news__item effect delay-4"></li>
            <li class="news__item effect delay-5"></li>
            <li class="news__item effect delay-6"></li>
          </ul>
        </div>
      </section>
    </main>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>
まとめてふわっとver.と違うのは、
・ulではなくli全てに「effectクラス」がついている
・liに「delay-1~6クラス」がついている
点です。offsクラスは変わらずにulにつけます。
【jQuery】
まとめてふわっとver.と同じです。編集不要です。

【CSS】

/*ふわっと表示*/

.news__items.offs .effect {
  opacity: 0;
  transform: translate(0, 100px);
  -webkit-transform: translate(0, 100px);
}
.news__items.ons .effect {
  opacity: 1;
  -webkit-transform: translate(0, 0);
  transform: translate(0, 0);
  -webkit-transition: all 2s ease;
  transition: all 2s ease;;
}

/*以下、遅延の設定*/
.news__items.ons .delay-1 {
  -webkit-transition-delay: 0.5s;
  transition-delay: 0.5s;
}

.news__items.ons .delay-2 {
  -webkit-transition-delay: 1s;
  transition-delay: 1s;
}

.news__items.ons .delay-3 {
  -webkit-transition-delay: 1.5s;
  transition-delay: 1.5s;
}

.news__items.ons .delay-4 {
  -webkit-transition-delay: 2s;
  transition-delay: 2s;
}

.news__items.ons .delay-5 {
  -webkit-transition-delay: 2.5s;
  transition-delay: 2.5s;
}

.news__items.ons .delay-6 {
  -webkit-transition-delay: 3s;
  transition-delay: 3s;
}
ふわっとまとめてver.と違うところは「遅延の設定」をしている点です。
・それぞれのliのアニメーション開始を遅らせるために、delay1~6クラスにそれぞれ「transition-delay」プロパティを設定します。
→記事の下部に書いた追記をぜひご覧ください🙇‍♀️

最後にコードとデモを一応載せます↓

追記:data-delay属性

私は上記の方法で実装したのですが、その後jQueryのコードを書いた株式会社Ficusの社長さん(@ficus_at_osaka)の書きたてQiitaの記事を読んで、data-delay属性を知りました。

順番に遅延して表示させる場合はdata-delay属性にトリガーしてから遅延する秒数を設定しておくと、transition-delayが付くのでちょっと便利です。(@ficus_at_osakaさんのQiitaから引用)

個別にふわっとさせる後半のコードに追加して使います。

htmlに

<li class="effect" data-delay="0.2">
<li class="effect" data-delay="0.4">
<li class="effect" data-delay="0.6">

のように遅延の時間を設定することで、CSSにtrandition-delayプロパティがついてくれるのだそうです。

これは便利ですね..!次から使います!!

詳細のQiita記事はこちらです↓

あとがき

ちょっと簡単ではありますが、今日は以上です。CSSでアニメーションを付けることで、動きも軽くなりました!

案件を優先していると、どうしてもアウトプットが遠のいてしまうので、少しハードルを落としてでも細々アウトプットしていきたいと思っています。

もし、コードに誤りがあった場合は教えていただけると助かります🙇‍♀️

★Thanks:師匠「もりけんさん」(@terracetec)

もりけんさんのHPはこちら