今回はjQueryでスクロール時に要素を下からふわっとフェードインさせる方法を初心者でもわかりやすいように図解で説明します。
デモ
以下にデモを用意しました。スクロールすると下からふわっとフェードインします。
See the Pen
by wagashi000327 (@wagashi000327)
on CodePen.
スクロール時に要素をフェードインさせる方法
HTML
<div class="wrapper">
<div class="element">
<p>この要素がフェードインします。</p>
</div>
<div class="element">
<p>この要素がフェードインします。</p>
</div>
<!-- 以下同じ -->
</div>
HTMLは特に解説するポイントはありません。共通のクラスを入れておくくらいです。
CSS
.element {
/* 最初は非表示 */
opacity: 0;
visibility: hidden;
transform: translateY(30px);
transition: opacity 1s, visibility 1s, transform 1s;
}
/* フェードイン時に入るクラス */
.is-fadein {
opacity: 1;
visibility: visible;
transform: translateX(0);
}
フェードインさせたい要素に対してCSSでopacity: 0; visibility: hidden;
を指定して非表示にしておきます(opacity
だけだと透過はできるがリンクの判定が残ったりするのでvisibility
も入れる)。
また下からふわっと表示させたいのでtransform: translateY(30px);
を指定してちょっと下に配置しておきます。
さらにアニメーションさせるためにtransition
も入れます。
transition: 1s;
でもいいのでは?と思うかもしれませんが、transition-property
を省略すると何かと変なバグが起きやすいので、面倒でも毎回指定しておいたほうがいいです。
この状態でスクロール時に.is-fadein
クラスを入れるとtransform
とopacity
とvisibility
が上書きされ、transition
で指定した秒数で下からふわっとフェードインしてくれます。
jQuery
$(function () {
$(window).scroll(function () {
const windowHeight = $(window).height();
const scroll = $(window).scrollTop();
$('.element').each(function () {
const targetPosition = $(this).offset().top;
if (scroll > targetPosition - windowHeight + 100) {
$(this).addClass("is-fadein");
}
});
});
});
スクロールイベントを発火させ、$(window).height();
でウィンドウの高さ、$(window).scrollTop();
でスクロール量を取得します。
次にeach()
を使ってフェードインさせたい要素全てに処理をかけます。each()
の中で$(this)
を使うとそれぞれの要素を取得できます。今回は$('.element').each(function() {})
としているので、それぞれの.element
という要素が取得できるわけです。
次にフェードインさせたいそれぞれの要素の上からの距離を$(this).offset().top;
で取得します。
そしていちばん重要なのがif (scroll > targetPosition - windowHeight + 100)
の部分ですね。これは条件を1つずつ見ていくとわかりやすいです。
ここは何をしているのかというと、例えば要素の上からの距離(targetPosition
)を500px、ウィンドウの高さ(windowHeight
)を300pxとして、これを図にすると以下のようになります。距離を測るときの基準は左上からです。
ここでまず、scroll > targetPosition
までの条件を図にすると以下のような感じになります。
このようにscroll > targetPositioin
としてしまうとウィンドウの一番上を過ぎたときに条件がtrueとなり、フェードインしてしまいます。
なのでここからウィンドウの高さ分の距離をマイナスする必要があります。ここまでの条件がif (scroll > targetPosition - windowHeight)
です。
しかしウィンドウの高さ分をまるっとマイナスすると、今度はウィンドウの一番下でフェードインしてしまい見えなくなってしまいます。
そこで今度は逆にある程度高さをプラスしてやることでウィンドウの一番下からちょっと上の部分でフェードインさせることができます。
これを条件にするとif (scroll > targetPosition - windowHeight + 100)
となるわけです。
つまり後ろの+ 100
の部分は「ウィンドウの下から何px上のところでフェードインしてほしいか?」ということです。
これで下からふわっとフェードインさせることができます!
PC幅とSP幅で下からの距離を変えたい場合
PC幅を基準でウィンドウ下からの距離を決めていると、SP幅で見たときに思ったより画面の上の方でフェードインしてしまい微妙かもしれません。
そこでPC幅とSP幅で下からの距離を変えてみます。
コードはこんな感じです。
$(function () {
$(window).scroll(function () {
const wHeight = $(window).height();
const scrollAmount = $(window).scrollTop();
// ここから追加
let buffer;
if ($(window).width() > 768) {
buffer = 300;
} else {
buffer = 100;
}
// ここまで追加
$('.js-fadein').each(function () {
const targetPosition = $(this).offset().top;
// 下からの距離を変数に置き換え
if (scrollAmount > targetPosition - wHeight + buffer) {
$(this).addClass("is-fadein");
console.log(buffer);
}
});
});
});
ウィンドウ下からの余白部分をPCとSPで分岐させることで下からの距離を分岐できます。スクロールするたびにif文を通るのでresizeイベントは必要ありません。
まとめ
下からふわっとフェードインさせるアニメーションでは、フェードインさせる位置が理解しにくいかもしれませんが、最初はなんとなくでも大丈夫です。何度か使っているうちに少しずつわかってくるものです。
下からフェードインさせるのは色んなサイトで使うアニメーションだと思うのでできるようになっておくといいと思います!