ある位置を過ぎたら切り替わる スクロールの動き

通称:スクロールトリガーScroll Trigger

切り替わる線

見本の中をスクロールしてください。セクションが画面の線を越えると、背景の色が切り替わります。

セクションが画面の決まった線を越えたところで、ページの背景の色が切り替わります。スクロールの量ではなく「どこまで来たか」で1回切り替えるので、話の区切りが伝わります。

自分のサイトの中身で、この形を作らせる指示文です。最初の「サイトの情報」を書き換えてから渡します。今あるページを直させるときは、その HTML を貼ります。

この形で作る
# 動かすもの(ここを書き換える)
- 動かす要素:〈例:各セクションの見出しとカード、商品の写真〉
- 今あるページ:〈今のページに付けるなら、その HTML と CSS を貼る。新しく作るなら空ける〉

# 動きの呼び名
一般に「スクロールトリガー」(Scroll Trigger)と呼ばれる動きです。

# 作ってほしい動き
Scroll Trigger(ある位置を過ぎたら切り替わる)。セクションが画面の決まった線(画面のまん中)を越えたら、ページの背景の色をそのセクションの色に切り替える。

# 動き
- きっかけ:IntersectionObserver の rootMargin を "-50% 0px -50% 0px" にして、線を越えたセクションを見つける
- IntersectionObserver に root: document を付ける(iframe の中や埋め込みでも、線どおりに動くように。付けないと rootMargin が無視されることがある)
- セクションごとの色は HTML の data-bg に書き、html の CSS 変数(--stg-bg)に入れる
- 背景の色は transition: background-color 0.6秒 で切り替える
- 上へ戻ったときも、線の上にあるセクションの色に戻す

# 付ける場所
- 縦に長いページのセクション

# 守ってほしいこと
- scroll イベントで位置を計算しない(IntersectionObserver を使う)
- 文字の色と背景の色の差(コントラスト)は、どの色に切り替わっても 4.5:1 以上にする

# 軽さと配慮(どの動きでも守る)
- 動かすのは transform と opacity だけにする(top・left・width・height・margin は動かさない)
- 動きを控える設定(prefers-reduced-motion: reduce)のときは動かさず、最後の状態で表示する
- 画面に入ったかは IntersectionObserver で見る。scroll イベントで毎回位置を測らない
- JavaScript が動かない環境でも中身が見えるようにする(最初に隠す指定は、JavaScript が付ける class の下に書く)
- will-change を付けるなら動いている間だけにする

# 出力
- 足す CSS と JavaScript を分けて出す。ライブラリは使わない
- 時間・距離・速さの変わり方は CSS 変数にまとめ、あとから変えやすくする
- 今あるページを渡したときは、HTML に足す class や属性だけを書き、ほかの見た目は変えない

スクロールに合わせて切り替わる・進む・留まる動きを18種類の型に分け、AIへの指示文・スクロールして試せる見本・コードを載せています。見本の中をスクロールすると動きを確かめられ、下のつまみや選択肢を変えると、指示文とコードの値も同じものに変わります。

スクロールの動きはどの型を選ぶか

スクロールの動きは、読む人が自分の手で動かす動きです。時間で勝手に動く登場の動きとちがい、止めれば止まり、戻せば戻ります。そのぶん、操作の感触を変えてしまう型(画面に長く留める・スクロールを乗っ取る)は、読む人を待たせたり迷わせたりしやすくなります。まず「位置で1回切り替えるのか、量に合わせて進めるのか、画面に留めるのか」を決め、留める型は長さを控えめにします。

こんなとき 向いている型
章ごとに雰囲気を変えたいある位置を過ぎたら切り替わる
長い記事やマニュアルで、いまの位置を見せたい目次の、いま読んでいる位置が光る・読んだ量を示すバー
制作の流れ・沿革を読み進めてほしいスクロールした量に合わせて進む
短いメッセージを1行ずつ届けたい読み進めると文字が濃くなる
スクロールの量ではなく、画面に入ったときに文字を動かしたい1文字ずつ順番に出る・マーカーが引かれるなど(文字の動き)
写真に奥行きを出したい奥と手前で動く速さが変わる・写真が近づいて広がる
製品をスクロールで回して見せたい・マウスに合わせて奥行きを出したい連番の絵がコマ送りで進む(画像シーケンス)・マウスパララックス(画像の動き)
見出しを見せたまま、説明を読ませたい片側は留めて、もう片側が流れる
手順や考え方を1つずつ見せたいカードが上に重なっていく・画面に留めたまま、中身が入れ替わる
作品や事例を横に並べて見せたい縦のスクロールで横に進む・1枚ずつぴたっと止まる
1枚のページの中をメニューで移動させたいページ内のリンクで、なめらかに移動する
写真の一覧に遊びを足したい速くスクロールすると傾く

どの型でも守ること

  1. scroll イベントで位置を計算しない。位置で切り替える型は IntersectionObserver、量に合わせる型は CSS の animation-timeline で作ります。スクロールのたびに計算が走ると、スクロールがかくつきます。
  2. 使えないブラウザでも読める形にする。animation-timeline は @supports で囲み、使えないブラウザ(2026年10月時点の Firefox)では、動かずに中身が読める形にします。
  3. 動きを控える設定の人には、視差や拡大を動かさない。画面に留めて入れ替える型は、留めずに縦に並べます。読む人が自分で動かすだけの型(sticky・snap)はそのままで構いません。
  4. スクロールを乗っ取らない。ページ全体に慣性を付けるライブラリや、ホイールの量を変える仕組みは、読む人の操作感を変えてしまいます。
  5. 画面に留める長さは、画面3枚分くらいまでにする。それより長いと、スクロールしても先へ進まないと感じさせます。

よくある質問 (FAQ)

ここの14型は、ライブラリなしで作れます。量に合わせて進む型は CSS の scroll-driven animations(animation-timeline)、位置で切り替える型は IntersectionObserver で足ります。いくつもの動きを細かく連ねる演出や、Firefox でも同じ動きが要るときに、ライブラリを検討します。

動かずに、最後の状態がそのまま見えます。ここのコードは、animation-timeline を使う指定をすべて @supports (animation-timeline: view())(読んだ量を示すバーは scroll())の中に書いています。画面に留める型は、使えないブラウザでは留めずに縦に並べたり、ふつうの横スクロールにしたりして、中身を読めるようにしています。読んだ量を示すバーは、0 のまま残さず、バーごと出しません。

ページ内のリンクでなめらかに移動させたいだけなら、CSS の scroll-behavior: smooth の1行で足ります。ページ全体のスクロールに慣性を付けるライブラリは、ホイールやトラックパッドの手ごたえが変わり、思ったところで止まれなくなります。入れるなら、動きを控える設定の人には効かせないようにします。