捲動時縮小的標頭是常見的 UI 模式,當使用者向下捲動時,頁面頂端的固定標頭元素會流暢地縮小。這種效果通常用於盡可能擴大主要內容的螢幕空間,同時保留必要的導覽或品牌元素。有了 CSS 捲動式動畫,您就能將動畫連結至文件的捲動位置,以宣告式且高效能的方式達成這項效果。
導入方式
以下說明如何建立捲動時縮小的標頭:
建立固定標頭:首先,建立固定在頁面頂端且高度預先定義的標頭元素。
<header>HEADER</header>header { position: fixed; height: 200px; top: 0; left: 0; right: 0; }定義縮小動畫:建立 CSS 動畫,變更標頭的高度。
@keyframes shrink { to { height: 50px; } }套用動畫和捲動時間軸:將動畫附加至標頭,並使用
scroll()函式將動畫連結至文件的捲動位置。header { animation: shrink auto linear both; animation-timeline: scroll(block root); }設定
animation-range:使用animation-range屬性指定動畫應發生的捲動距離。舉例來說,如要在捲動前 150 像素時縮小標頭,請使用animation-range: 0px 150px;。header { animation-range: 0px 150px; }
提示:為避免標頭遮住後續內容,請在 body (或主要內容容器) 中加入 padding-top,其值應等於標頭的初始高度。
提示:為確保頁面內容與縮小的標頭同步捲動,請將 animation-range-end 設為起始大小和結束大小之間的差異。這樣一來,動畫就會在標頭達到最終大小時準確完成。在這個示範中,標頭會從 200px 縮小至 50px,因此 animation-range-end 設為 150px。
範例程式碼
@keyframes shrink {
to {
height: 50px;
}
}
header {
animation: shrink auto linear both;
animation-timeline: scroll(block root);
animation-range: 0px 150px;
}
最佳做法
使用捲動驅動動畫時,請務必遵循幾項最佳做法,確保體驗流暢且無障礙:
- 務必加入功能偵測:並非所有瀏覽器都支援捲動驅動動畫。使用
@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%))檢查支援情形,並為不支援的瀏覽器提供備用方案。- 這裡必須加入
(animation-range: 0% 100%)檢查,篩除僅部分支援的瀏覽器。 - 請勿使用
scroll-timeline-polyfill套件做為備用策略,因為該套件的功能不完整,且有許多已知問題。 - 如果動畫僅用於裝飾,請選擇漸進增強,且「不要」提供備用方案。
- 這裡必須加入
- 務必尊重使用者偏好:部分使用者偏好網頁上較少動態效果。使用
prefers-reduced-motion媒體查詢,為這些使用者停用或減少動畫。 - 建議只為高效能 CSS 屬性製作動畫:如要讓動畫最流暢,請只為瀏覽器合成器執行緒可處理的屬性製作動畫,例如
transform和opacity。為width或height等其他屬性建立動畫,可能會導致效能問題。 - 建議使用正確的宣告順序:使用
animation簡寫屬性時,請在之後宣告animation-timeline和animation-range,以免簡寫重設時間軸。
使用 scroll() 函式建立捲動驅動動畫時:
- 選用:明確指定捲動器。如果不是指定最接近的上層捲動器,請使用
scroll(root)或scroll(self)明確指定要使用的捲動器。- 如果
root、nearest或self不足,請使用命名的捲動時間軸。
- 如果
- 選用:明確指定要追蹤的軸:如果不是指定預設的
block軸 (例如在水平捲軸中),請明確指定要追蹤的軸,使用scroll(block)或scroll(inline)。
針對這個特定用途:
- 在
animation-range中使用百分比時,要建立動畫的元素「不得」為position: static或position: relative。- 這是因為這些元素會被視為「在流程中」。在捲動時縮小這些元素,會縮小總捲動距離,進而影響計算值,例如
10%捲動。
- 這是因為這些元素會被視為「在流程中」。在捲動時縮小這些元素,會縮小總捲動距離,進而影響計算值,例如
瀏覽器支援和備用策略
因此,通常需要備用策略。
如果瀏覽器不支援捲動驅動動畫,可以使用備用方案重新建立視覺效果。備用方案通常是使用捲動事件監聽器 (用於 ScrollTimeline 效果) 或 IntersectionObserver API (用於 ViewTimeline 效果) 建構。
如果瀏覽器內建支援捲動式動畫,請一律使用原生 CSS 實作,因為這類實作的效能較佳。
請注意,並非所有效果都能使用備用方法重新建立。
針對這個用途,下列指令碼會為不支援捲動驅動動畫的瀏覽器套用備用方案。它會使用捲動事件監聽器,追蹤文件在 150px 距離內的捲動位置,並據此更新標頭高度。
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: scroll()) and (animation-range: 0% 100%)')) {
const header = document.querySelector('header');
const initialHeight = 200;
const finalHeight = 50;
const scrollDistance = 150;
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const scrollPercent = Math.min(1, scrollY / scrollDistance);
const newHeight = initialHeight - (initialHeight - finalHeight) * scrollPercent;
header.style.height = `${newHeight}px`;
});
}