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);
}

純 CSS 實驗性語法 (未來趨勢)

現代瀏覽器(如 Chrome 115+)已經開始支援 animation-timeline,這讓你可以完全不寫 JS 就達成捲動動畫。

@keyframes fade-out {
  from { opacity: 0; }
  to { opacity: 1; }
}

.scroll-reveal {
  animation: fade-out linear;
  animation-timeline: view(); /* 捲動到可視範圍時驅動 */
  animation-range: entry 20% cover 40%;
}
請注意:animation-timeline 雖然強大,但目前的瀏覽器支援度(特別是 Safari 和舊版瀏覽器)尚不完整。在生產環境使用時,請務必提供備份方案(Fallback)。

實務技巧

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