最近接到一个需求,要求滚动内容时每次滚动一屏,调研后发现有css属性实现的方式,顺便研究了一下。
一、scroll-snap简介
CSS的scroll-snap属性可以使浏览器停止滚动时,如果目标元素在视窗内则自动滑动到目标位置。
适用场景:移动端的商品展示,整屏翻页/滚动/滑动。
二、scroll-snap实现的效果
三、scroll-snap属性
作用在滚动容器上 | 作用在滚动子项上 |
---|---|
- scroll-snap-type - scroll-snap-stop - scroll-padding/scroll-padding-* |
- scroll-snap-align - scroll-margin/scroll-margin-* |
最关键的两个属性是scroll-snap-type 和 scroll-snap-align。
scroll-snap-type 指明滚动方向和方式。
scroll-snap-align 指明滚动后捕捉的位置。
scroll-snap-type
scroll-snap-type属性定义在滚动容器中的一个临时点(snap point)如何被严格的执行。此属性不能用来指定任何精确的动画或者物理运动效果来执行临时点,而是交给用户代理来处理。
/* 关键值 */
scroll-snap-type: none;
当这个滚动容器的课时的viewport是滚动的,它必须忽略临时点
scroll-snap-type: x;
滚动容器只捕捉其水平轴上的捕捉位置。
scroll-snap-type: y;
滚动容器只捕捉其垂直轴上的捕捉位置。
scroll-snap-type: block;
滚动容器仅捕捉到其块轴上的捕捉位置。
scroll-snap-type: inline;
滚动容器仅捕捉到其内联轴上的捕捉位置。
scroll-snap-type: both;
滚动容器会独立捕捉到其两个轴上的位置(可能会捕捉到每个轴上的不同元素)
/* 可选 mandatory | proximity*/
scroll-snap-type: x mandatory;
mandatory表示如果它当前没有被滚动,这个滚动容器的可视视图将静止在临时点上。
意思是当滚动动作结束,如果可能,它会临时在那个点上。
如果内容被添加、移动、删除或者重置大小,滚动偏移将被调整为保持静止在临时点上。
scroll-snap-type: y proximity;
proximity表示如果它当前没有被滚动,这个滚动容器的可视视图将基于用户代理滚动的参数去到临时点上。
如果内容被添加、移动、删除或者重置大小,滚动偏移将被调整为保持静止在临时点上。
scroll-snap-type: both mandatory;
/* etc */
/* 全局值 */
scroll-snap-type: inherit;
scroll-snap-type: initial;
scroll-snap-type: unset;
以y轴的滚动为例,来看看mandatory和proximity的对比
点击查看【codepen】
可以看出 mandatory属性意味着浏览器必须捕捉到每个滚动点,假设scroll-snap-align属性有一个start值。这意味着,滚动必须对齐到滚动容器的开始处。
而proximity属性意味着如果合适,浏览器可能会捕捉到捕捉点。同样假设设置scroll-snap-align: start 当滚动距离很小的时候,在滚动距离很大的时候 停止滚动后滚动内容会停止在其停止的点上, 滚动内容自动吸附到scroll-snap-align定义的点上,这个具体的距离由浏览器决定。
scroll-snap-align
取值为start、center、end表示内容在滚动容器中对齐的点, 由滚动方向决定,如果是x轴滚动则start表示元素的左边源,
center是元素中间,end是元素右边源;如果是y轴滚动,start表示元素的上边源,center中间,end是元素下边源。
以scroll-snap-type: y mandatory为例,来看看start、center、end的表现:
点击查看【codepen】
scroll-padding/scroll-margin
scroll-padding 和 scroll-margin 就相当于 padding / margin。可以控制滚动元素和边界之间的留白。
scroll-snap-stop
scroll-snap-stop的默认值是normal, 如果用户滚动太快,就有可能跳过某些项。
要强制滚动捕捉到每个可能的点,应使用always。这样,用户可以一次滚动到一个捕捉点,这种方式有助于避免跳过重要内容。
兼容性
参考:
https://css-tricks.com/practical-css-scroll-snapping/
https://juejin.cn/post/6917034338479669262#heading-11
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap