Webページを閲覧しているときに、スクロールしていてビューポート内に要素が入ったらアニメーションが動き始める、というケースは沢山見かけると思います。そのように動かす方法をここで学んでいきましょう。
CSSだけでスクロール検知してアニメーションさせる
CSSスクロール連動は、Safari 26正式リリース(2025年秋頃)から実用開始か
今までは、ビューエリアに要素が表示されるタイミングの検知は、JavaScriptで行うのが一般的でした。
Chromeにて、CSSスクロール連動機能が2023年7月ごろにリリースされ、Safariでは2025年秋に正式リリースの方向でベータ版が6月にリリースされています。Firefoxでは、設定で有効化できますが、正式リリースの時期は未定です。
2024年6月~2025年6月のシェアは、Chrome 56.12%, Safari 25.54%, Edge 10.67%, Firefox 3.39%となっています。
一般的にFirefoxの利用率は非常に低いので、Safariの正式リリースをもって実用化が開始され始めるでしょう。
Browser Market Share Japan
https://gs.statcounter.com/browser-market-share/all/japan
無名スクロール進行タイムライン – animation-timeline: scroll();
この例では、3つのitem要素に対して、1つ目3つ目には透明度、2つ目には縦位置に対してアニメーションを設定しています。
無名スクロール進行タイムライン – animation-timeline: scroll();
https://developer.mozilla.org/ja/docs/Web/CSS/animation-timeline/scroll
アニメーション範囲
https://developer.mozilla.org/en-US/docs/Web/CSS/animation-range
HTML
<div class="flex-wrap-col3">
<div class="item fuwari">
<a data-fancybox="group1" data-src="./image/image-beach.jpg" data-caption="Beach">
<img src="./image/image-beach.jpg" alt="beach" />
</a>
<h3>Beach</h3>
</div>
<div class="item downup">
<a data-fancybox="group1" data-src="./image/image-lake.jpg" data-caption="Lake">
<img src="./image/image-lake.jpg" alt="lake" />
</a>
<h3>Lake</h3>
</div>
<div class="item fuwari">
<a data-fancybox="group1" data-src="./image/image-tram.jpg" data-caption="Tram">
<img src="./image/image-tram.jpg" alt="tram" />
</a>
<h3>Tram</h3>
</div>
</div>
CSS
/*Scroll Animation*/
/*フワッと表示*/
@keyframes scroll-opacity {
0% {
opacity: 0%;
}
100% {
opacity: 100%;
}
}
.fuwari {
opacity: 0; /*初期値*/
animation: scroll-opacity linear both; /*アニメーション設定*/
animation-timeline: scroll(); /*無名スクロール進行タイムライン*/
animation-range: entry -10% entry 40%; /*アニメーション範囲:ビューポートに対するアニメーション開始・終了位置*/
}
/*下から上へずれる*/
@keyframes scroll-up {
0% {
transform: translateY(20%); /*Y軸(縦方向)下側に20%ずらす*/
}
100% {
transform: translateY(0); /*Y軸(縦方向)要素の元の位置*/
}
}
.downup {
transform: translateY(20%);
animation: scroll-up linear both; /*アニメーション設定*/
animation-timeline: scroll(); /*無名スクロール進行タイムライン*/
animation-range: entry -10% entry 30%; /*アニメーション範囲:ビューポートに対するアニメーション開始・終了位置*/
}
今までJavaScriptを使って実装していた動きを、CSSだけでシンプルに実装できました。
JavaScriptで画面内へ入ったときに発火する Intersection Observer API
CSSによるanimation-timelineプロパティはスクロール量に応じてアニメーションの進行度を変化させるものですが、ビューポートに要素が入ったことを検知させ、アニメーションを発動させたい、という場合もあります。
そのような場合は、Intersection Observer APIを使ってJavaScriptによってクラス名を付与することでCSSアニメーションを動かします。
この例では、動かしたい要素のHTMLに「observerTarget」クラスをつけ、CSSアニメーション用のクラス「vibrate」のCSS定義を書き、JavaScriptでは「observerTarget」クラスの要素がビューポート内に入ったら、「inActive」クラスを付与するよう、処理を書いています。
HTML
監視対象の要素に「observerTarget」クラスをつけておきます。
「vibrate」クラスは、CSSでアニメーションの設定をするためのものです。
<a class="btn-gform vibrate observerTarget" data-fancybox="gform" data-src="#modal-gform" href="javascript:;">お問い合わせフォーム</a>
CSS
JavaScriptで、見える範囲に「observerTarget」クラスの要素が入ったら、「inActive」クラスが付与されるので、2つのクラスが付いた時に発動するCSSアニメーションの設定を書いておきます。
この例では、animista.netからCSSアニメーションの設定を持ってきたあと、「inActive」クラスを追加しています。
/*AnimistaからのCSS+inActiveクラス*/
.vibrate.inActive {
animation: vibrate 0.5s linear 3 both;
}
@keyframes vibrate {
0% {
-webkit-transform: translate(0);
transform: translate(0);
}
20% {
-webkit-transform: translate(-2px, 2px);
transform: translate(-2px, 2px);
}
40% {
-webkit-transform: translate(-2px, -2px);
transform: translate(-2px, -2px);
}
60% {
-webkit-transform: translate(2px, 2px);
transform: translate(2px, 2px);
}
80% {
-webkit-transform: translate(2px, -2px);
transform: translate(2px, -2px);
}
100% {
-webkit-transform: translate(0);
transform: translate(0);
}
}
JavaScript
監視対象=observerTargetクラス、交差したらinActiveクラスを付与する処理をJavaScriptで定義しています。
「observerTarget」クラスはHTML内で複数の要素に設定可能です。
const target = document.querySelectorAll('.observerTarget');
const options = {
root: null, /*null時はビューポート*/
rootMargin: "10px", /*交差を検知するルート要素からの距離*/
threshold: 0, /*交差判定 交差量が0になった瞬間=見え始めと見え終わり*/
};
const observer = new IntersectionObserver(inActiveFunc, options);
target.forEach((tgt) => {
observer.observe(tgt);
});
//要素が交差したときの指示
function inActiveFunc(entries) {
entries.forEach((entry) => {
const target = entry.target;
if (entry.isIntersecting) {
target.classList.add('inActive');
}
});
}
ID位置への移動時にスムーススクロール – scroll-behavior: smooth;
上のセクションで説明したスクロールアニメーションとは少し異なるのですが、aタグのhrefでジャンプ先を設定している場合で、ID名(#を含んだ名前)をセットした場合で、ページ内の移動時にアニメーションしながらページ内を移動させるための設定方法です。
html要素に対してscroll-behavior: smooth; を設定するだけです。
CSS
html {
scroll-behavior: smooth;
}
