【乾貨】使用 CSS Scroll Snap 優化滾動,提高用戶體驗!

做者:Ahmad
譯者:前端小智
來源:ishadee
點贊再看,微信搜索 大遷世界,B站關注【 前端小智】這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

最近開源了一個 Vue 組件,還不夠完善,歡迎你們來一塊兒完善它,也但願你們能給個 star 支持一下,謝謝各位了。css

github 地址:https://github.com/qq44924588...前端

你是否常常但願有一個CSS特性能夠輕鬆建立一個可滾動的容器? CSS scroll snap 能夠作到這一點。在早期的前端開發中,我依靠 JS 插件來建立滑塊組件。有時,咱們須要一種簡單的方法來快速將元素製做成可滾動的容器。如今,多虧了 CSSS scroll snap ,咱們能夠簡單作到這一點。vue

爲何要使用 CSS Scroll Snap

隨着移動設備和平板設備的興起,咱們須要設計和構建能夠輕觸的組件。 以圖庫組件爲例。 用戶能夠輕鬆地向左或向右滑動以查看更多圖像,而不是分層結構。git

clipboard.png

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

滾動容器的基礎知識

要建立一個滾動容器,如下是咱們須要作的基本內容web

  • 使用 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

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

滾動容器有什麼問題

問題是,與滑動相比,它們並不能提供良好的體驗。在觸摸屏上滑動手勢的主要好處是,咱們能夠用一根手指水平或垂直滾動。工具

圖片描述

實際上須要將每一個項目移動到它本身的位置。這並非滑動,這是一種很是糟糕的體驗,經過使用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;
}

圖片描述

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/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索