使用 CSS Scroll Snap 優化滾動,提升使用者體驗!

前端小智發表於2021-10-22
作者:Ahmad
譯者:前端小智
來源:ishadee

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

你是否經常希望有一個CSS特性可以輕鬆建立一個可滾動的容器? CSS scroll snap 可以做到這一點。在早期的前端開發中,我依靠 JS 外掛來建立滑塊元件。有時,我們需要一種簡單的方法來快速將元素製作成可滾動的容器。現在,多虧了 CSSS scroll snap ,我們可以簡單做到這一點。

為什麼要使用 CSS Scroll Snap

隨著移動裝置和平板裝置的興起,我們需要設計和構建可以輕觸的元件。 以相簿元件為例。 使用者可以輕鬆地向左或向右滑動以檢視更多影像,而不是分層結構。

clipboard.png

根據CSS規範,為開發者提供良好控制的滾動體驗是引入 CSS scroll snap的主要原因之一。它增強了使用者體驗,並使其更容易實現滾動體驗。

滾動容器的基礎知識

要建立一個滾動容器,以下是我們需要做的基本內容

  • 使用 overflow
  • 一種將專案彼此相鄰顯示(內聯)的方法

舉個例子:

<div class="section">
  <div class="section__item">Item 1</div>
  <div class="section__item">Item 2</div>
  <div class="section__item">Item 3</div>
  <div class="section__item">Item 4</div>
  <div class="section__item">Item 5</div>
</div>
.section {
  white-space: nowrap;
  overflow-x: auto;
}

多年來,使用white-space: nowrap是一種流行的CSS解決方案,用於強制元素保持內聯。不過,現在我們基本都使用 Flexbox :

.section {
  display: flex;
  overflow-x: auto;
}

clipboard.png

這是建立滾動容器的基本方法。然而,這還不夠,這不是一個可用的滾動容器。

滾動容器有什麼問題

問題是,與滑動相比,它們並不能提供良好的體驗。在觸控式螢幕上滑動手勢的主要好處是,我們可以用一根手指水平或垂直滾動。

圖片描述

實際上需要將每個專案移動到它自己的位置。這並不是滑動,這是一種非常糟糕的體驗,通過使用CSS scroll snap,我們可以通過簡單地定義snap points來解決這個問題,它將使使用者更容易地水平或垂直滾動。

接著,我們來看看如何使用CSS scroll snap

CSS Scroll Snap 簡介

要在容器上使用scroll snap,它的子專案應該內聯顯示,這可以用我上面解釋的方法之一來實現。我選擇CSS flexbox:

<div class="section">
  <div class="section__item">Item 1</div>
  <div class="section__item">Item 2</div>
  <div class="section__item">Item 3</div>
  <div class="section__item">Item 4</div>
  <div class="section__item">Item 5</div>
</div>
.section {
  display: flex;
  overflow-x: auto;
}

了這個,我們需要新增另外兩個屬性來讓scroll snap工作。我們應該在哪裡新增它們?

首先,我們需要將scroll-snap-type新增到滾動容器中。 在我們的示例中,是.section元素。 然後,我們需要向子項(即.section__item)新增scrolln-snap-align

.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

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

這裡你可能想知道x mandatorystart是幹嘛用的。 不用擔心,這是本文的核心,下面會對其進行深入的講解。

圖片描述

這一刻,我對CSS scroll snap非常興奮,它使滾動更加自然。現在,讓我們深入研究scroll snap 屬性。

Scroll Snap Type

根據CSS規範scroll-snap-type 屬性定義在滾動容器中的一個臨時點(snap point)如何被嚴格的執行。

滾動容器的軸線

滾動容器的軸表示滾動方向,它可以是水平或垂直的,x值表示水平滾動,而y表示垂直滾動。

/* 水平*/
.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x;
}

/* 垂直*/
.section {
  height: 250px;
  overflow-y: auto;
  scroll-snap-type: y;
}

clipboard.png

Scroll Snap 容器的嚴格性

我們不僅可以定義Scroll Snap的方向,還可以定義它的嚴格程度。這可以通過使用scroll-snap-type值的andatory | proximity來實現。

mandatory:如果它當前沒有被滾動,這個滾動容器的可視檢視將靜止在臨時點上。意思是當滾動動作結束,如果可能,它會臨時在那個點上。如果內容被新增、移動、刪除或者重置大小,滾動偏移將被調整為保持靜止在臨時點上。

mandatory關鍵字意味著瀏覽器必須捕捉到每個滾動點。假設roll-snap-align屬性有一個start值。這意味著,滾動必須對齊到滾動容器的開始處。

在下圖中,每次使用者向右滾動時,瀏覽器都會將專案捕捉到容器的開頭。

clipboard.png

.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

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

圖片描述

試著在下面的演示中向右滾動。如果你使用的是手機或平板電腦,可以向右移動滾動條或使用觸控。應該能感受到每個專案是如何從其容器的開始抓取的。

演示地址:https://codepen.io/shadeed/pe...

但是,如果該值是proximity,則瀏覽器將完成這項工作,它可能會吸附到定義的點(在我們的例子中start)。注意,proximity 是預設值,但是為了清晰起見,我們這裡還是宣告一下它。

clipboard.png

.section {
  display: flex;
  overflow-x: auto;
  /* proximity is the default value, I added it for clarity reasons */
  scroll-snap-type: x proximity;
}

圖片描述

這裡順便給大家推薦一個親測好用的雲資料庫MemFire Cloud,做個小應用,他的免費額度就綽綽有餘。

Scroll Snapping Alignment

滾動容器的子專案需要一個對齊點,它們可以對齊到這個點。我們可以用start, centerend

為了更容易理解,下面是它的工作原理。

clipboard.png

假設我們在滾動容器上有一塊磁鐵,這將有助於我們控制捕捉點。 如果scroll-snap-type是垂直的,則對齊對齊將是垂直的。 參見下圖:

clipboard.png

滾動容器的 start

子專案將吸附到其水平滾動容器的開始處。

圖片描述

滾動容器的 center

子專案將吸附到其滾動容器的中心。

圖片描述

滾動容器的 end

子項將對齊到其滾動容器的末尾。

圖片描述

使用 Scroll-Snap-Stop

有時,我們可能需要一種方法來防止使用者在滾動時意外跳過一些重要的項。如果使用者滾動太快,就有可能跳過某些項。

.section__item {
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}

法動太快可能會跳過三個或四個專案,如下所示:

圖片描述

scroll-snap-stop的預設值是normal,要強制滾動捕捉到每個可能的點,應使用always

.section__item {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

圖片描述

這樣,使用者可以一次滾動到一個捕捉點,這種方式有助於避免跳過重要內容。 想象每個停止點都有一個停止標誌,參見下面的動畫:

圖片描述

演示地址:https://codepen.io/shadeed/pe...

Scroll Snap Padding

scroll-padding設定所有側面的滾動邊距,類似於padding屬性的工作方式。 在下圖中,滾動容器的左側有50px的內邊距。 結果,子元素將從左側邊緣捕捉到50px

clipboard.png

直滾動也是如此。參見下面的示例:

.section {
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  scroll-padding: 50px 0 0 0;
}

clipboard.png

Scroll Snap Margin

scroll-margin設定滾動容器的子項之間的間距。 在向元素新增邊距時,滾動將根據邊距對齊。 參見下圖:

clipboard.png

.item-2具有scroll-margin-left: 20px。 結果,滾動容器將在該專案之前對齊到20px。 請注意,當使用者再次向右滾動時,.item-3會捕捉到滾動容器的開頭,這意味著僅具有邊距的元素將受到影響。

CSS Scroll Snap 用例

圖片列表

scroll snap 的一個很好的用例是影像列表,使用 scroll snap 提供更好的滾動體驗。

clipboard.png

.images-list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x;
  gap: 1rem;
  -webkit-overflow-scrolling: touch; /* Important for iOS devices */
}

.images-list img {
  scroll-snap-align: start;
}

注意,我使用x作為scroll-snap-type的值。

圖片描述

事例地址:https://codepen.io/shadeed/pe...

好友清單

滾動捕捉的另一個很好的用例是朋友列表。 下面的示例摘自Facebook(一個真實的示例)。

clipboard.png

.list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 1rem;
  scroll-padding: 48px;
  padding-bottom: 32px;
  -webkit-overflow-scrolling: touch;
}

.list-item {
  scroll-snap-align: start;
}

請注意,滾動容器的padding-bottom:32px。 這樣做的目的是提供額外的空間,以便box-shadow可以按預期顯示。

clipboard.png

頭像列表

對於此用例,我感興趣的是將center作為scroll-snap-align的值。

clipboard.png

.list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.list-item {
  scroll-snap-align: center;
}

這在一個角色列表中是很有用的,角色在滾動容器的中間是很重要的

圖片描述

演示地址:https://codepen.io/shadeed/pe...

全屏展示

使用scroll snap也可以用於垂直滾動,全屏展示就是一個很好的例子。

clipboard.png

<main>
  <section class="section section-1"></section>
  <section class="section section-2"></section>
  <section class="section section-3"></section>
  <section class="section section-4"></section>
  <section class="section section-5"></section>
</main>
main {
  height: 100vh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
}

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

圖片描述

塊和內聯

值得一提的是,對於scroll-snap-type,可以使用inlineblock邏輯值。參見下面的示例

main {
  scroll-snap-type: inline mandatory;
}

可讀性

使用 CSS scroll snap時,請確保可訪問性。 這是滾動對齊的一種不好用法,它阻止使用者自由滾動內容以讀取內容。

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

h2 {
  scroll-snap-align: start;
}

clipboard.png

圖片描述

請務必不要這樣做。

總結

這是我剛剛學到的一個新的CSS特性的長篇文章。我希望它對你有用。

我是小智,我們下期在見!


程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

原文:https://ishade.com/article/cs...

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588... 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章