捲動驅動動畫是網路上常見的 UX 模式。捲動驅動動畫會連結至捲動容器的捲動位置。也就是說,當您向上或向下捲動時,連結的動畫會直接回應,向前或向後清除。例如視差背景圖片或捲動時會移動的閱讀指標。
開發人員通常會使用 JavaScript 回應主執行緒上的捲動事件,藉此建立捲動驅動動畫。由於捲動事件是採非同步方式傳送,且通常位於主執行緒上,因此很難建立與捲動同步的流暢捲動驅動動畫,經常導致卡頓。
不過,隨著瀏覽器推出新的 CSS 和 UI 功能,您現在可以建立宣告式捲動驅動動畫。捲動時間軸和檢視時間軸是整合現有 Web Animations API (WAAPI) 和 CSS Animations API 的新概念,現在只要幾行程式碼,就能讓捲動驅動的動畫在主執行緒外流暢執行。歡迎參閱本案例研究,瞭解 Tokopedia、redBus 和 Policybazaar 如何運用這項新功能獲益。
Tokopedia
Tokopedia 以捲動驅動動畫取代先前的自訂 JavaScript 實作,藉此提升網頁效能,並改善電子商務轉換漏斗的整體瀏覽體驗。
相較於使用傳統的 JavaScript 捲動事件,我們成功減少了多達 80% 的程式碼行數,並發現捲動時的平均 CPU 使用率從 50% 降至 2% ── Andy Wihalim, Tokopedia 資深軟體工程師
程式碼
下列實作項目使用 scroll()
函式,設定匿名捲動進度時間軸,以控制 CSS 動畫的進度。最上方的固定式橫幅會根據定義的 animationRange
內捲動位置而顯示/隱藏。
const toggleBar = keyframes({
to: { height: 48 },
});
export const cssWrapper = css({
position: 'fixed',
left: 0,
width: '100vw',
pointerEvents: 'none',
marginTop: 120,
height: 0,
overflow: 'hidden',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
animation: `${toggleBar} linear both`,
animationTimeline: 'scroll()',
animationRange: '20px 70px',
});
redBus
redBus 在「待辦事項」到達網頁上,為行動裝置和電腦提供不同的動畫,並在轉換漏斗的早期階段向所有使用者顯示。有了捲動驅動動畫,他們就能以 CSS 取代這些自訂 JavaScript 實作項目,達到相同效果。
用途
相片庫 (行動版適用「圖片顯示」,電腦版適用「封面流動」)。
代碼 (行動裝置)
在先前的範例中,Tokopedia 使用了匿名捲動進度時間軸。在下列程式碼中,redBus 使用具名檢視區塊進度時間軸。動畫會變更元素最近的祖先捲動器 (在本例中為相片庫捲動器) 內定義的 animation-range
中,<img>
元素的 opacity
和 clip-path
。
const reveal = keyframes`
from {
opacity: 0;
clip-path: inset(45% 20% 45% 20%);
}
to {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}`
const CardImage = styled.div`
width: 100%;
height: 100%;
img {
border-top-left-radius: 0.75rem;
border-top-right-radius: 0.75rem;
height: 100%;
width: 100%;
object-fit: cover;
view-timeline-name: --revealing-image;
view-timeline-axis: block;
/* Attach animation, linked to the View Timeline */
animation: linear ${reveal} both;
animation-timeline: --revealing-image;
/* Tweak range when effect should run*/
animation-range: entry 25% cover 50%;
}
`;
我們很高興看到這項功能,因為它完美融合了效能與更優質的體驗,有助於提升搜尋引擎最佳化 (SEO) 的網頁體驗信號。此外,這項工具的學習曲線很平緩,因此是每個電子商務網站的必備工具。其他團隊也給予正面回饋和支持,讓我們能將 SDA 運用於更多使用者歷程。— redBus 資深工程經理 Amit Kumar。
Policybazaar
比較保險方案是使用者重複執行的重要動作,可做為決策過程的指引。Policybazaar 使用捲動驅動動畫,在使用者捲動表格時縮小低優先權元素的大小。這項調整可提升可讀性,同時提供流暢的捲動體驗。
我們運用捲動驅動動畫,盡量擴大檢視區塊空間,方便使用者比較方案,確保閱讀體驗專注且不雜亂。—Rishabh Mehrotra,PolicyBazaar 人壽保險事業部設計主管。
animate-timeline
。程式碼
與 Tokopedia 的上一個範例類似,Policybazaar 使用 scroll()
函式設定匿名捲動進度時間軸,藉此控制 CSS 動畫的進度。在本例中,系統會根據定義的 animation-range
內捲動位置,縮小字型大小並淡化標題。
@supports (animation-timeline: scroll()) {
.plan-comparison .inner-header {
animation: move-and-fade-header linear both;
}
.plan-comparison .left-side {
animation: shrink-name linear both;
}
.plan-comparison .inner-header, .plan-comparison .left-side {
animation-timeline: scroll();
animation-range: 0 150px;
}
}
@keyframes move-and-fade-header {
to {
translate: 0% -5%;
top:103px;
}
}
@keyframes shrink-name {
to {
font-size: 1.5rem;
}
}
在使用者歷程中,捲動驅動的動畫是常見模式
所有精選電子商務公司都在含有資訊卡的頁面上使用捲動驅動動畫,讓資訊卡產生動畫效果,吸引使用者注意。下列範例顯示使用者歷程不同階段的卡片捲動效果。如要達成這個目標,通常會使用匿名檢視進度時間軸來控制自訂 CSS 動畫的進度,如下列 CSS 程式碼片段所示。
@keyframes animate-in {
0% { opacity: 0; transform: translateY(10%); }
100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
0% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-10%); }
}
.flyin_animate {
animation: animate-in linear forwards;
animation-timeline: view();
animation-range: entry;
}
redBus (首頁)
Policybazaar (產品資訊頁面)
Tokopedia (產品詳細資料頁面)
使用 Scroll-driven Animations API 的注意事項
您可以為不支援的瀏覽器填補捲動驅動動畫,例如使用 Scroll-timeline polyfill。如果這麼做,您就必須進行額外測試,確保該項目能與架構順利搭配運作,且使用 Polyfill 的瀏覽器不會發生動畫失敗或不穩定的情況。
在 CSS 中,您可以使用 @supports
測試是否支援動畫時間軸,再使用捲動驅動的動畫。例如:
@supports (animation-timeline: scroll()) {
}
資源
- 捲動驅動動畫的示範
- 使用捲動驅動動畫,在捲動時為元素加上動畫效果
- 程式碼研究室:開始使用 CSS 中的捲動驅動動畫
- Chrome 擴充功能:捲動驅動動畫偵錯工具
- 捲動時間軸 Polyfill
- 要回報錯誤或提出新功能建議嗎?我們想聽聽你的看法!
本系列的其他文章將說明電子商務公司如何運用檢視畫面轉場效果、Popover、容器查詢和 has()
選取器等新 CSS 和 UI 功能獲益。