根據 CSS Scroll Snap Module Level 1 規範,CSS 新增了一批能夠控制滾動的屬性,讓滾動能夠在僅僅通過 CSS 的控制下,得到許多原本需要 JS 腳本介入才能實現的美好交互。 Tips:本文截的一些 Gif 圖涉及容器滾動,效果不是很好,可以點進 Demo 里實際感受下 ...
根據 CSS Scroll Snap Module Level 1 規範,CSS 新增了一批能夠控制滾動的屬性,讓滾動能夠在僅僅通過 CSS 的控制下,得到許多原本需要 JS 腳本介入才能實現的美好交互。
Tips:本文截的一些 Gif 圖涉及容器滾動,效果不是很好,可以點進 Demo 里實際感受下。
sroll-snap-type
首先看看 sroll-snap-type
可能算得上是新的滾動規範裡面最核心的一個屬性樣式。
scroll-snap-type:屬性定義在滾動容器中的一個臨時點(snap point)如何被嚴格的執行。
光看定義有點難理解,簡單而言,這個屬性規定了一個容器是否對內部滾動動作進行捕捉,並且規定瞭如何去處理滾動結束狀態。
語法
{ scroll-snap-type: none | [ x | y | block | inline | both ] [ mandatory | proximity ]? }
舉個例子,假設,我們希望一個橫向可滾動容器,每次滾動之後,子元素最終的停留位置不是尷尬的被分割,而是完整的呈現在容器內,可以這樣寫:
<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
表示強制將滾動結束後元素的停留位置設置到我們規定的地方。
左邊是正常滾動容器的寫法,右邊是添加了 scroll-snap-
之後:
如果是 y 軸方向的滾動也是一樣的,只需要簡單改一下 scroll-snap-type:
ul { scroll-snap-type: y mandatory; }
CodePen Demo -- CSS Scroll Snap Demo
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 訂閱收藏。
如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。