精準操控的滾動體驗,淺談新標準 Scroll Snap

NimitzDEV發表於2019-03-03

在最近更新的 Chrome 69 穩定版中,全面支援了 CSS Scroll Snap 標準。該標準用於設定一個滾動捕捉點,讓最終的滾動位置附著於就近或特定型別的捕捉點中,以達到更好的滾動體驗。今天我們就來研究一下。

瀏覽器支援情況

精準操控的滾動體驗,淺談新標準 Scroll Snap

什麼是捕捉

學過 CAD 系列軟體的同學可能很清楚,我們在移動一個物件時,物件總能夠自動吸附在柵格線上,使得物件只能落在柵格上的確定位置上,這就是柵格捕捉。或者這樣說,在一個普通的量尺上,規定你的畫筆只能落在 1mm 和 2mm 的刻度上,而不能落在他們之間。

什麼是滾動捕捉

滾動捕捉,即在滾動時對滾動位置進行捕捉。我們先來看看 W3C 提供的兩個例子:

例1:使用一系列圖片堆放在一個橫向的可滾動容器中形成一個類似相簿的容器,通過使用基於元素的位置捕捉,使得滾動結束時某個圖片的位置將始終落在滾動視口的中心位置。

img {
    /* 指定每張圖片的捕捉位置與滾動容器可視區域 x 軸中心的位置對齊 */
    scroll-snap-align: none center;
}
.photoGallery {
    width: 500px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    /* 要求每次滾動的結束的位置精確地落在捕捉點上 */
    scroll-snap-type: x mandatory;
}
複製程式碼
<div class="photoGallery">
    <img src="img1.jpg">
    <img src="img2.jpg">
    <img src="img3.jpg">
    <img src="img4.jpg">
    <img src="img5.jpg">
</div>
複製程式碼

img

圖中的紅色區域即為可滾動容器的可視區域或叫捕捉視口。圖片黃色框的地方被稱為捕捉區域。我們上面設定的 scroll-snap-align 中指定了橫軸捕捉點為中心位置。此時將在捕捉視口區域中心(紅色虛線)以及捕捉區域中心(黃色虛線)形成捕捉點。

例2:在本例中,將一份分頁的文件的滾動位置捕捉在每一頁文件靠近滾動容器的地方。這種非精確的捕捉能夠讓上一頁文件的末尾出現在捕捉點(容器邊緣)的附近,讓使用者能夠感知到還沒有到達所有文件的最頂部的效果。並且使用非精確的捕捉能夠讓使用者在滾動中途隨時停止,而不會像精確捕捉一樣會強制將滾動位置”修正“到捕捉點上。然而在使用非精確捕捉時,如果滾動結束點已經位於捕捉點的附近,瀏覽器將會將最終的滾動點修改為指定的捕捉點上。

.page {
    /* 指定每一頁文件的頂部為捕捉的位置 */
    scroll-snap-align: start none;
}
.docScroller {
    width: 500px;
    overflow-x: hidden;
    overflow-y: auto;
    /* 指定捕捉視口應有 100px 的上內邊距 */
    scroll-padding: 100px 0 0;
    /* 使用非精確捕捉,能允許滾動最終停止在捕捉點的附近而不需要進一步的調整 */
    scroll-snap-type: y proximity;
}
複製程式碼
<div class="docScroller">
    <div class="page">Page 1</div>
    <div class="page">Page 2</div>
    <div class="page">Page 3</div>
    <div class="page">Page 4</div>
</div>
複製程式碼

img

如上圖所示,首先是確定捕捉視口,由於使用了 scroll-padding 我們的捕捉視口與滾動可視區域有一個上邊距為 100px 的距離,通過使用 scroll-snap-align 確定了捕捉區域的捕捉點位於區域的縱軸開始的位置

好,做個小結,我們已經知道,要形成捕捉需要以下幾個條件:

  1. 是個可滾動的區域
  2. 確定捕捉視口和捕捉區域的捕捉點

那麼接下來我們就帶著上面的例子來慢慢了解控制這些引數的幾個屬性吧

捕捉視口相關控制

scroll-snap-type

通過設定 scroll-snap-type 將一個滾動容器轉變為一個滾動捕捉容器,並且可以控制捕捉的嚴格度,如果沒有指定嚴格度,預設為非精確的捕捉(proximity)。

scroll-snap-type 支援設定兩個引數,第一個為捕捉軸向,第二個引數為捕捉嚴格度,可省略。

捕捉軸向

捕捉軸向有x, y, block, inline 以及 both 數值。

x: 捕捉影響捕捉視口 x 軸方向

y: 捕捉影響捕捉視口的 y 軸方向

block: 捕捉影響塊軸方向

inline: 捕捉影響行軸方向

both: 捕捉分別影響所有方向

捕捉嚴格度

none: 不捕捉

mandatory:精確捕捉

proximity:非精確捕捉

例如:

html {
    scroll-snap-type: y mandatory;
}
複製程式碼

在文件的滾動捕捉中,捕捉視口對 y 軸方向進行精確捕捉。

scroll-padding

scroll-padding 指定了捕捉視口的與滾動容器之間的內邊距,能夠使得開發者更好的控制進行捕捉的區域。scroll-padding 的引數與我們常見的 padding 引數形式相同,同時也有 padding 一樣的 scroll-padding-top 等屬性。

捕捉區域相關控制

scroll-margin

scroll-margin 則是指定了捕捉區域與捕捉元素之間的邊距。例如對捕捉區域設定了 scroll-margin: 20px; 那麼實際上生成的捕捉區域會比捕捉元素的尺寸大。 scroll-margin 的引數與我們常見的 margin 引數形式相同,同時也有 margin 一樣的 scroll-margin-top 等屬性。

scroll-snap-align

scroll-snap-align 屬性指定了滾動區域和捕捉視口的捕捉位置,並且作為所有捕捉區域相對與捕捉視口的對齊位置。例如設定 scroll-snap-align 為 center 時,滾動區域的捕捉位置位於中心位置,捕捉視口的捕捉位置則為 scroll-snap-type 中指定方向的中心位置。

scroll-snap-align 可以分別設定 x、y 或是 行、塊 方向上的捕捉對齊。如果第二個引數忽略,那麼 x、y 方向的值均為第一個引數指定的值。

scroll-snap-type 可以有如下的屬性值:

none: 未定義

start: 對齊開始位置

end: 對齊結束位置

center: 對齊中心位置

例如:

.item {
    scroll-snap-align: none start;
}
複製程式碼

小結

通過上面的例子我們可以清楚地看到,使用 CSS Scroll Snap 特性很好地把控了滾動結束的位置,將使用者想看的內容立即展現出來。目前僅有部分瀏覽器完整得支援了最新的 CSS Scroll Snap 標準,期待其他大廠的加入。

致謝

感謝劉觀宇對文章的糾錯以及標題建議,感謝黃小璐對文章的糾錯。

參考資料

  1. www.w3.org/TR/css-scro…
  2. webdesign.tutsplus.com/tutorials/h…

相關文章