CSS 捲動偵測動畫 (Scroll-Triggered Animations)

當使用者向下捲動網頁時,元素優雅地「淡入」或「滑入」畫面,可以增加網頁的動態感並引導使用者的注意力。

傳統上這需要 JavaScript 監聽 scroll 事件,但現代 CSS 已經開始支援原生的捲動驅動動畫(Scroll-driven animations)。不過為了廣泛的瀏覽器相容性,目前主流做法仍是 CSS 配合 Intersection Observer API

基本淡入效果 (Fade-in)

我們先定義動畫的初始狀態與結束狀態。

/* 初始狀態:透明且位移 */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.8s ease-out;
}

/* 顯示狀態:不透明且回到原位 */
.reveal.active {
  opacity: 1;
  transform: translateY(0);
}
<div class="reveal">淡入效果!</div>

實作預覽

請向下捲動此區域內容 ↓
淡入效果!

配合少量 JavaScript (推薦做法)

這是目前最穩定且效能良好的做法。

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('active'); // 當元素進入視野時加入 class
    }
  });
});

// 選取所有需要動畫的元素
document.querySelectorAll('.reveal').forEach((el) => observer.observe(el));

各種滑入特效

除了垂直淡入,你還可以嘗試不同的方向或縮放效果。

左側滑入 (Slide-in Left)

.slide-left {
  opacity: 0;
  transform: translateX(-50px);
  transition: all 1s ease;
}

.slide-left.active {
  opacity: 1;
  transform: translateX(0);
}

縮放進入 (Zoom-in)

.zoom-in {
  opacity: 0;
  transform: scale(0.8);
  transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.zoom-in.active {
  opacity: 1;
  transform: scale(1);
}

原生捲動驅動動畫 (Scroll-Driven Animations)

現代瀏覽器已經開始支援原生的捲動驅動動畫,讓你可以完全不寫 JS 就達成複雜的捲動效果。

animation-timeline: view()

當元素進入或離開可視範圍 (Viewport) 時觸發動畫。

@keyframes reveal {
  from {
    opacity: 0;
    clip-path: inset(45% 20% 45% 20%);
  }
  to {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }
}

.revealing-image {
  animation: reveal linear both;
  animation-timeline: view();
  /* 定義動畫在元素進入 25% 到進入 75% 之間執行 */
  animation-range: entry 25% entry 75%;
}

animation-timeline: scroll()

根據特定容器的捲動進度來驅動動畫,最常用於「頁面頂端的捲動進度條」。

@keyframes grow-progress {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.progress-bar {
  animation: grow-progress linear;
  animation-timeline: scroll(root); /* 追蹤整個頁面的捲動 */
  transform-origin: left;
}

理解 animation-range

animation-range 用來精確控制動畫開始與結束的時機:

  • entry:元素開始進入視窗。
  • exit:元素開始離開視窗。
  • cover:元素完全覆蓋視窗的過程。
animation-timeline 雖然強大,但目前的瀏覽器支援度(特別是 Safari 和舊版瀏覽器)尚不完整。在生產環境使用時,請務必提供備份方案(如前面介紹的 Intersection Observer)。

實務技巧

  1. 僅執行一次 vs 持續執行:在 Intersection Observer 中,你可以設定在顯示過一次後就停止觀察(unobserve),這樣使用者往回捲動時就不會重複播放動畫,體驗較為穩重。
  2. ** staggered 延遲執行**:如果在同一個區塊有多個項目(如產品清單),可以給予不同的 transition-delay,讓它們像骨牌一樣依序出現。
  3. 優先順序:頁面最上方的內容(首屏)建議直接顯示,不要加上捲動動畫,以確保使用者第一時間就能看到資訊。
捲動動畫的核心在於「節制」。只有當它能幫助傳達內容或引導視覺時,它才是有價值的。