發布於 2023-09-06

更新於 2023-09-06

程式

約2210字 (12分鐘閱讀)

[譯文] Practical CSS Scroll Snapping

Title Image

Photo by Wikimedia Commons on Wikimedia Commons

原文連結: Practical CSS Scroll Snapping, by Max Kohler

在此的 snap 部份翻譯為吸附,部份翻譯為捕捉,總之在這裡代表同等含意:3

CSS Scroll Snapping (CSS 滾動捕捉) 允許在使用者完成滾動後將視窗鎖定在某些元素或位置上,這對於構建像這樣的互動效果非常有用:

example

Live Demo

Basic usage

滾動捕捉 (Scroll Snapping) 是通過在容器元素上設置 scroll-snap-type 屬性,以及在其中的元素上設置 scroll-snap-align 屬性來使用的。

當容器元素滾動時,它將捕捉到使用者定義的子元素。

在最基本使用的情況下像這樣:

<div class="container">
  <section class="child"></section>
  <section class="child"></section>
  <section class="child"></section>
  <p>...</p>
</div>
.container {
  scroll-snap-type: y mandatory;
}

.child {
  scroll-snap-align: start;
}

這與規範的第一版不同,第一版允許使用 "repeat" 關鍵詞手動設置捕捉點:

.container {
  /* OLD */
  scroll-snap-points-y: repeat(300px);
}

上面的方法相當有限,因為它僅允許均勻間隔的捕捉點,所以無法真正構建一個能夠捕捉到不同大小元素的介面,如果元素在不同屏幕尺寸上變形也可能會遇到問題。

可以同時使用這兩種方法(如果佈局允許的話)來支持這兩組瀏覽器:

.container {
  scroll-snap-type: mandatory;
  scroll-snap-points-y: repeat(300px);
  scroll-snap-type: y mandatory;
}

.child {
  scroll-snap-align: start;
}

父容器屬性

與任何屬性一樣,熟悉它們接受的值是一個好主意。

滾動捕捉屬性適用於父元素和子元素,每個元素都有特定的值。

有點像 flexbox 和 grid 的工作方式,其中父元素變成了 "flex" 或 "grid" 容器。

在這種情況下,可以這麼說父元素變成了一個"捕捉"容器。

以下是父容器的屬性和值以及它們的工作方式。

scroll-snap-type “mandatory” vs. “proximity”

"mandatory" 值表示瀏覽器必須在使用者停止滾動時捕捉到一個捕捉點。

"proximity" 屬性則不太嚴格,它表示瀏覽器可能在看似適當的情況下捕捉到一個捕捉點。

根據我的經驗,當停止滾動時離捕捉點只有幾百像素時,這個情況才會發生。

根據我的個人工作,"mandatory" 值可以提供更一致的用戶體驗,但正如規範所指出的那樣,它也可能具有一定風險。

想像一個情境,其中一個滾動容器內的元素比視窗還要高:

example

如果該容器設置為 scroll-snap-type: mandatory,則它將始終吸附到該元素的頂部或下方的元素的頂部,使得無法滾動到高元素的中間部分。

scroll-padding

默認情況下,內容將吸附到容器的邊緣。

可以通過在容器上設置 scroll-padding 屬性來更改這一默認行為。它遵循與常規 padding 屬性相同的語法。

如果佈局中存在可能妨礙內容的元素 (比如固定標題),它可能就很有用。

子元素屬性

現在讓我們繼續討論子元素的屬性。

scroll-snap-align

scroll-snap-align - CSS: Cascading Style Sheets | MDN

這允許使用者指定元素的哪一部分應該吸附到容器上。

它有三種可能的值:startcenterend

example

這些值是相對於滾動方向的。

如果垂直滾動,start 指的是元素的頂部邊緣。

如果水平滾動,start 指的是左邊緣。

centerend 遵循相同的原則。

使用者可以為每個滾動方向設置不同的值,用空格分隔。

scroll-snap-stop "normal" vs. "always"

"scroll-snap-stop" | Can I use... Support tables for HTML5, CSS3, etc

默認情況下,滾動吸附只在使用者停止滾動時啟動,這意味著它們可以跳過多個吸附點,然後才會停止。

可以通過在任何子元素上設置 scroll-snap-stop: always 來更改這一行為。

這將強制滾動容器在使用者繼續滾動之前停在該元素上。

現在讓我們看一些滾動吸附的使用示例。

Example 1: Vertical list 垂直滾動

要實現垂直吸附滾動只需要幾行 CSS 代碼。首先告訴容器在其垂直軸上吸附:

.container {
  scroll-snap-type: y mandatory;
}

然後定義吸附點(snap points),在這裡我們指定每個列表元素的頂部將是一個吸附點:

.child {
  scroll-snap-align: start;
}

Example 2: Horizontal slider 水平滑塊

為了實現水平滑塊,我們告訴容器沿其 x 軸對齊。我們還使用 scroll-padding 來確保子元素在容器中心處對齊。

.container {
  scroll-snap-type: x mandatory;
  scroll-padding: 50%;
}

然後,我們告訴容器要吸附到哪些點。為了使畫廊(gallery)居中,我們將每個元素的中心點定義為一個吸附點。

.child {
  scroll-snap-align: center;
}

Example 3: Vertical full screen 垂直全螢幕滾動

我們可以直接在元素上設置吸附點:

html { /* body won't work ¯\_(ツ)_/¯ */
  scroll-snap-type: y mandatory;
}

然後使每個部分的大小等於視窗的大小,並將頂部邊緣定義為一個吸附點:

section {
  height: 100vh;
  width: 100vw;
  scroll-snap-align: start;
}

Example 4: Horizontal full screen 水平全螢幕滾動

這與垂直版本的概念相同,但吸附點在 x 軸上。

body {
  scroll-snap-type: x mandatory;
}

section {
  height: 100vh;
  width: 100vw;
  scroll-snap-align: start;
}

Example 5: 2D image grid 2D 圖像網格

滾動捕捉可以在同一時間在兩個方向上工作。

同樣地,我們可以直接在元素上設置 scroll-snap-type

.container {
  scroll-snap-type: both mandatory;
}

然後將每個瓷磚的左上角定義為一個吸附點:

.tile {
  scroll-snap-align: start;
}
Some thoughts on user experience 關於用戶體驗的一些想法

對於使用者體驗來說,干擾滾動行為是一個具有風險的做法。

由於滾動是與網頁互動的基本部分,任何方式的更改都可能感到突兀——過去通常會使用詞語 "scrolljacking" 來描述這種體驗。

基於 CSS 的滾動捕捉 (scroll snapping) 的優點在於無需直接控制滾動位置。

反之只需向瀏覽器提供一個位置列表,以一種適合平台、輸入法和用戶喜好的方式做吸附處理。這意味著你構建的滾動界面在任何平台上查看時都會感覺就像本地界面(例如使用相同的動畫等)。

對我(作者 Max Kohler)來說,這是 CSS 滾動捕捉優於提供類似功能的 JavaScript 庫的主要優勢。

根據我的經驗,這在移動設備上效果相當不錯,也許這是因為滾動捕捉已經是移動平台上本地界面的一部分。

(想像一下 iOS 和 Android 上的主屏幕 —— 它們本質上是帶有吸附點的水平滑塊。)

特別是在 Android 上的 Chrome 上,的交互非常好,因為它感覺像常規滾動,但視口總是恰好在吸附點停止滾動:

這背後肯定需要一些需要高度技巧的數學才能實現這一點。多虧了 CSS 滾動捕捉,我們可以輕鬆實現這一功能。

當然,我們不應該對所有內容都使用吸附點。

像文章頁面之類的內容通常不需要它們。

但我認為在適當的情況下可以成為一種不錯的增強功能 ———— 圖庫、幻燈片展示似乎是不錯的候選項,不過也許還有其他潛力。

Conclusion

如果用心思考,滾動捕捉 (scroll snapping) 可以成為一個有用的設計工具。

CSS 吸附點允許連接到瀏覽器的本地滾動交互,使界面感覺無縫且流暢。

隨著 JavaScript API 的出現,這些功能將變得更加強大。

然而輕微的接觸可能是正確的選擇。(Still, a light touch is probably the way to go.)(這句怎麼翻都怪怪的)

[譯文] Practical CSS Scroll Snapping

https:///blog/94

作者

Kama

恭喜! 這裡是終點站喔 :3
Read more from 程式
lightbox-image
Toggle Button - Red Pandas Icons by svgrepo.com

Copyrights © 2023 Kama, All Rights Reserved.