宣告捲動貼齊位置,建立控制良好的捲動體驗。
網頁開發人員可透過 CSS 捲動快照功能宣告捲動快照位置,打造控管良好的捲動體驗。分頁文章和圖片輪播是兩個常見的例子。CSS Scroll Snap 提供易於使用且一致的 API,可建構這些熱門的 UX 模式。
背景
捲動貼齊的用途
捲動是與網頁內容互動的常見方式,這是平台提供更多資訊的原始方式,可讓使用者一次查看更多內容,在螢幕空間有限的行動平台尤其重要。因此,網頁作者越來越傾向將內容整理成可捲動的扁平清單,而非深層階層,這並不令人意外。
捲動的主要缺點是精確度不足。捲動很少會與段落或句子對齊。如果捲動結束時,頁面或圖片只顯示一部分,這種情況在有意義的界線之間分頁或列出內容時會更加明顯。這些用途可受益於妥善控制的捲動體驗。
長期以來,網頁開發人員一直依賴以 JavaScript 為基礎的解決方案來控制捲動,以解決這項缺點。不過,由於缺少捲動自訂基本項目或複合捲動存取權,以 JavaScript 為基礎的解決方案無法提供完整保真度的解決方案。CSS Scroll Snap 可確保解決方案快速、高保真且易於使用,並在各瀏覽器中保持一致。
網頁作者可使用 CSS 捲動快照,為每個捲動容器標示捲動作業的完成界線。瀏覽器會根據捲動作業的詳細資料、捲動容器的版面配置和可見度,以及快速移動位置的詳細資料,選擇最合適的結束位置,然後平滑地動畫化至該位置。回到先前的例子,當使用者完成輪轉介面的捲動操作時,可見的圖片會自動對齊。JavaScript 不需調整捲動。

CSS 捲動貼齊
捲動對齊是指在捲動作業完成後,將捲動容器的捲動偏移量調整至偏好的對齊位置。
捲動容器可以使用 scroll-snap-type
屬性選擇啟用捲動對齊功能。這會告知瀏覽器,應考慮將這個捲動容器對齊後代元素產生的對齊位置。scroll-snap-type
可決定捲動發生的軸:x
、y
或 both
,以及對齊嚴格程度:mandatory
、proximity
。稍後會再詳細說明。
只要在元素上宣告所需對齊方式,即可產生對齊位置。這個位置是捲動偏移量,最接近的祖先捲動容器和元素會根據指定軸對齊。每個軸上可進行下列對齊:start
、end
、center
。
start
對齊方式是指捲動容器的對齊點起點邊緣,應與元素對齊區域的起點邊緣齊平。同樣地,end
和 center
對齊方式表示捲動容器的貼齊點終點邊緣或中心點,應與元素貼齊區域的終點邊緣或中心點對齊。
以下範例說明如何運用這些概念。
範例:水平圖庫
捲動貼齊的常見用途是圖片輪播。舉例來說,如要建立水平圖片輪播,讓使用者捲動時會自動對齊每張圖片,我們可以將捲動容器指定為在水平軸上強制對齊 scroll-snap-type
,並將每張圖片設為 scroll-snap-align: center
,確保對齊時會將圖片置中於輪播中。
#gallery {
scroll-snap-type: x mandatory;
overflow-x: scroll;
display: flex;
}
#gallery img {
scroll-snap-align: center;
}
<div id="gallery">
<img src="cat.jpg">
<img src="dog.jpg">
<img src="another_cute_animal.jpg">
</div>
由於吸附位置與元素相關聯,因此吸附演算法可以根據元素和捲動容器大小,智慧地決定吸附時機和方式。舉例來說,假設某張圖片大於輪轉介面,如果採用不成熟的對齊演算法,使用者可能無法平移畫面,查看完整圖片。但規格要求實作項目偵測到這種情況,並允許使用者在該圖片中自由捲動,只會貼齊圖片邊緣。
範例:歷程產品頁面
另一個常見的案例是,頁面有多個邏輯區段,可垂直捲動瀏覽,例如典型的產品頁面,這類頁面也很適合使用捲動貼齊功能。scroll-snap-type: y proximity;
更適合這類情況。使用者捲動至特定區段中間時,這個元件不會干擾,但使用者捲動至足夠接近的位置時,元件會自動對齊並將焦點帶到新區段。
方法如下:
article {
scroll-snap-type: y proximity;
/* Reserve space for header plus some extra space for sneak peeking. */
scroll-padding-top: 15vh;
overflow-y: scroll;
}
section {
/* Snap align start. */
scroll-snap-align: start;
}
header {
position: fixed;
height: 10vh;
}
<article>
<header> Header </header>
<section> Section One </section>
<section> Section Two </section>
<section> Section Three </section>
</article>
捲動邊框間距和邊界
產品頁面有固定位置的頂端標題。設計也要求在捲動容器貼齊時,頂端部分仍要保持可見,為使用者提供上方內容的設計提示。
scroll-padding
屬性是新的 CSS 屬性,可用於調整捲動容器或對齊點的有效可視區域,計算捲動對齊方式時會用到這個屬性。這個屬性會定義捲動容器的邊框間距方塊內插。在我們的範例中,頂端新增了 15vh
額外插邊,指示瀏覽器將捲動容器頂端邊緣下方的 15vh
位置視為垂直起始邊緣,用於捲動貼齊。在對齊時,對齊目標元素的起始邊緣會與這個新位置齊平,因此上方會留下空間。
scroll-margin
屬性會定義外凸量,用於調整吸附目標有效方塊,類似於 scroll-padding
在吸附捲動容器上的運作方式。
您可能已經注意到,這兩項屬性中都沒有「snap
」一詞。這是刻意設計,因為這些修飾符實際上會修改所有相關捲動作業的方塊,而不只是捲動對齊。舉例來說,Chrome 會在計算分頁捲動作業 (例如 PageDown 和 PageUp) 的網頁大小時,以及計算 Element.scrollIntoView()
作業的捲動量時,將這些值納入考量。
與其他捲動 API 互動
DOM Scrolling API
捲動貼齊會在所有捲動作業 (包括指令碼啟動的作業) 完成後發生。使用 Element.scrollTo
等 API 時,瀏覽器會計算作業的預期捲動位置,然後套用適當的對齊邏輯,找出最終對齊位置。因此,使用者指令碼不需要進行任何手動計算來進行對齊。
順暢捲動
平滑捲動會控制程式化捲動作業的行為,而捲動吸附則會決定目的地。由於這兩者控制的是捲動的正交層面,因此可以一起使用,相輔相成。
過度捲動行為
過度捲動行為 API 可控制捲動在多個元素間的串連方式,且不會受到捲動吸附影響。
注意事項和最佳做法
如果目標元素間距較大,請避免使用強制對齊。 這可能會導致無法存取兩個對齊位置之間的內容。
在許多情況下,捲動貼齊功能可做為強化功能新增,不需要進行功能偵測。如有需要,請使用 @supports
或 CSS.supports
偵測 CSS Scroll Snap 的支援情形。
請避免使用 scroll-snap-type
,因為已淘汰的規格中也有這個項目。
CSS 中的特徵偵測
@supports (scroll-snap-align: start) {
article {
scroll-snap-type: y proximity;
scroll-padding-top: 15vh;
overflow-y: scroll;
}
}
JavaScript 中的特徵偵測
if (CSS.supports('scroll-snap-align: start')) {
// use css scroll snap
} else {
// use fallback
}
請勿假設程式輔助捲動 API (例如 Element.scrollTo
) 一律會在要求的捲動位移處完成。程式輔助捲動完成後,捲動貼齊可能會調整捲動偏移。請注意,即使在捲動捕捉功能推出前,這也不是好的假設,因為捲動可能會因其他原因而中斷,但捲動捕捉功能尤其如此。
之後的作業
Chrome 團隊最近進行的問卷調查,重點就是捲動體驗。調查結果指出,外掛程式庫和 CSS 之間仍有差距,需要進一步縮小。我們接下來的重點將放在 scroll-snap
,包括: