使用 sroll-snap-type 優化滾動

根據 CSS Scroll Snap Module Level 1 規範,CSS 新增了一批可以控制滾動的屬性,讓滾動可以在僅僅經過 CSS 的控制下,獲得許多本來須要 JS 腳本介入才能實現的美好交互。css

Tips:本文截的一些 Gif 圖涉及容器滾動,效果不是很好,能夠點進 Demo 裏實際感覺下。html

 

sroll-snap-type

首先看看 sroll-snap-type 可能算得上是新的滾動規範裏面最核心的一個屬性樣式。git

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

光看定義有點難理解,簡單而言,這個屬性規定了一個容器是否對內部滾動動做進行捕捉,而且規定了如何去處理滾動結束狀態。瀏覽器

語法

{
    scroll-snap-type: none | [ x | y | block | inline | both ] [ mandatory | proximity ]?
}

舉個例子,假設,咱們但願一個橫向可滾動容器,每次滾動以後,子元素最終的停留位置不是尷尬的被分割,而是完整的呈如今容器內,能夠這樣寫:flex

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
ul {
    scroll-snap-type: x mandatory;
}

li {
    scroll-snap-align: center;
}  

上面 scroll-snap-type: x mandatory 中,x 表示捕捉 x 軸方向上的滾動,mandatory 表示強制將滾動結束後元素的停留位置設置到咱們規定的地方。flexbox

左邊是正常滾動容器的寫法,右邊是添加了 scroll-snap- 以後: spa

 

若是是 y 軸方向的滾動也是同樣的,只須要簡單改一下 scroll-snap-type:3d

ul {
    scroll-snap-type: y mandatory;
}

CodePen Demo -- CSS Scroll Snap Democode

 

scroll-snap-align 中的 mandatory 與 proximity

scroll-snap-align 中的另一個重點就是 mandatory 與 proximity。

  • mandatory: 一般在 CSS 代碼中咱們都會使用這個,mandatory 的英文意思是強制性的,表示滾動結束後,滾動中止點必定會強制停在咱們指定的地方

  • proximity: 英文意思是接近、臨近、大約,在這個屬性中的意思是滾動結束後,滾動中止點可能就是滾動中止的地方,也可能會再進行額外移動,停在咱們指定的地方

也就是說,如上指定了 scroll-snap-align: y proximity 的滾動容器,若是不額外設置 scroll-snap-margin/scroll-snap-padding,是有可能停在下面這樣~尷尬~的位置:

  

scroll-snap-type: both mandatory

固然,還有一種比較特殊的狀況是,scroll-snap-type: both mandatory,表示橫向與豎向的滾動,都會同時進行捕捉,也是能夠的:

 

CodePen Demo -- CSS Scroll Snap Both mandatory Demo

 

scroll-snap-align

使用 scroll-snap-align 能夠簡單的控制將要聚焦的當前滾動子元素在滾動方向上相對於父容器的對齊方式。

其須要做用在父元素上,可選值有三個:

{
    scroll-snap-align: start | center | end;
}

什麼意思呢,看看示意圖:

能夠類比單個元素在 flexbox 裏面的 justify-content 屬性的 flex-start | flex-end | center,規定當前元素在主軸上相對父容器的對齊方式去理解。

再看看實際的 Demo ,將 scroll-snap-align 添加到滾動子容器上:

 

scroll-snap-align: start

使當前聚焦的滾動子元素在滾動方向上相對於父容器頂部對齊。

 

scroll-snap-align: center

使當前聚焦的滾動子元素在滾動方向上相對於父容器中心對齊。

 

scroll-snap-align: end

使當前聚焦的滾動子元素在滾動方向上相對於父容器底部對齊。 

CodePen Demo -- CSS Scroll Snap Demo

 

不規則子元素滾動

若是子元素大小不一,也能有很是好的表現,使用 scroll-snap-align: center,使得不規則子元素在每次滾動後居於容器中間:

 

CodePen Demo -- CSS Scroll Snap 不規則子元素滾動 Demo

 

scroll-margin / scroll-padding

上述的 scroll-snap-align 很好用,能夠控制滾動子元素與父容器的對齊方式。然而可選的值只有三個,有的時候咱們但願進行一些更精細的控制時,可使用 scroll-margin 或者 scroll-padding

其中:

  • scroll-padding 是做用於滾動父容器,相似於盒子的 padding
  • scroll-margin 是做用於滾動子元素,每一個子元素的 scroll-margin 能夠設置爲不同的值,相似於盒子的 margin

舉個例子,在豎向滾動下,給滾動父容器添加一個 scroll-padding-top: 30px 等同於給每一個子元素添加 ``scroll-margin-top: 30px`:

咱們但願滾動子元素在 scroll-snap-align: start 的基礎上,與容器頂部的距離爲 30px:

<ul class="snap">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  ...
</ul>  
.snap {
    overflow-x: auto;
    scroll-snap-type: y mandatory;
    scroll-padding-top: 30px;
}

li {
    scroll-snap-align: start;
} 

總結一下就是,scroll-snap-align 能夠對滾動以後的對齊方式進行簡單控制,而配合 scroll-margin / scroll-padding 則能夠進行精確控制。

 

廢棄的 scroll-snap-points-x / scroll-snap-points-y

標準的發展過程,早年間的規範現在廢除,這個瞭解一下便可,新標準如今是這幾個,而且大部分瀏覽器已經兼容:

  • scroll-snap-type
  • scroll-snap-align
  • scroll-margin / scroll-padding
  • scroll-snap-stop

scroll-snap-stop 是一個仍處於實驗室的標準,本文沒有過多介紹,我本身在幾個不一樣瀏覽器嘗試了下,暫時沒有發現瀏覽器支持這個屬性,可是最新的標準裏面是有關於它的明確的定義的。

 

實際應用,漸進加強

在實際應用中,應用在全屏滾動/廣告banner上有不少用武之地:

 

CodePen Demo -- full screen scroll

固然,兼容性如今仍是很大的問題:

不過在不少場景下,就算 scroll-snap- 相關幾個屬性暫不兼容,也不會對正常使用形成影響,因此在不少場景,這些屬性均可以直接應用上去,對支持的瀏覽器提供更好的交互。

最後

好了,簡單的科普文,本文到此結束,但願對你有幫助 :)

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索