捲動動畫:用 animation-timeline 取代 IntersectionObserver
捲動動畫:用 animation-timeline 取代 IntersectionObserver
Scroll-driven animations 從根本上解決問題。這是你已知的 CSS 動畫,只有一個替換:不是時間驅動進度,而是捲動容器的位置。瀏覽器可以在合成器上執行它。
四行進度條
css
.progress {position: fixed;inset: 0 0 auto 0;height: 4px;transform-origin: left;animation: grow linear both;animation-timeline: scroll(root block);}@keyframes grow {from { transform: scaleX(0); }to { transform: scaleX(1); }}
捲動時顯示:view() 時間軸
css
.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}@keyframes fade-up {from { opacity: 0; transform: translateY(32px); }to { opacity: 1; transform: translateY(0); }}
四個命名範圍:entry、exit、cover(預設)、contain。
耗費一小時的陷阱:animation 簡寫重置時間軸
css
/* 損壞:簡寫將 animation-timeline 重置為 auto */.reveal {animation-timeline: view();animation-range: entry 0% entry 60%;animation: fade-up linear both;}
css
/* 正確:時間軸和範圍在簡寫之後 */.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}
命名時間軸
css
.gallery {overflow-x: auto;scroll-timeline: --gallery inline;}.gallery-indicator {animation: fill linear both;animation-timeline: --gallery;timeline-scope: --gallery;}
漸進增強在這裡不是可選的
css
.reveal {opacity: 1;}@supports (animation-timeline: view()) {@media (prefers-reduced-motion: no-preference) {.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}}}
陷阱與最佳實踐
- 只動畫化
transform和opacity。 - 永遠不要隱藏只有動畫才能揭示的內容。
- 「為什麼我的動畫靜止?」幾乎總是捲動容器的問題。
- 使用
both作為填充模式。 - 減少動態效果是醫療設定,不是禮貌。
- 不要刪除你仍然需要的 JavaScript。
總結
Scroll-driven animations 將關於主執行緒的相同想法應用於整個效果類別:需要捲動監聽器、觀察器和類別切換的東西變成了單一 CSS 屬性。