CSS Scroll Snap Points的思考

小序

今天呢,继续讲解一下CSS Scroll Snap Points新属性(^-^)

原文链接


CSS最近介绍了一个关于scroll snap points的新功能,为触控以及输入设备的用户提供一个流式、精确的滚动体验。

关于创建scroll snap效果,有许多jquery插件可供你选择,但是我们今天所讲述的不是通过安装一个插件来控制滚动的行为,而是使用原生的CSS scroll snap points来实现。

Scroll Snap Points工作原理

通过在x以及y轴上定义“snap points”来控制滚动容器的滚动行为。当用户在水平或者垂直方向滚动时,利用snap点,滚动容器会snap到内容区域的某一点。

水平 Snap Points

创建一个可滚动的图片画廊,用户可以滚动或滑动每幅图片。代码结构如下:

1
2
3
4
5
6
<div class="gallery">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
<img src="4.jpg">
</div>

首先,创建一个水平的滚动容器,在.gallerydiv容器上定义了overflow以及white-space样式:

1
2
3
4
5
6
7
8
9
10
.gallery {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
width: 1000px;
}

img {
width: 100%;
}

代码中的.gallery代表滚动容器;内部的水平滚动视口大小为1000px

接下来,我们先来认识几个定义水平scroll snap points的相关属性。

scroll-snap-points-x

scroll-snap-points-x属性用来设置滚动容器内部水平的snap点。定义和.gallery一样宽度的snap点,用户可以滚动并且snap每一个图片:

1
2
3
4
5
.gallery {
...
width: 1000px;
scroll-snap-points-x: repeat(1000px);
}

x轴设置snap点值为repeat(1000px),始于0px并重复于1000px区间内,也就是滚动容器的宽度。现在需要启动snap点了。

scroll-snap-type

scroll-snap-type属性用于启动滚动容器内所有的snap点。使用这个属性定义滚动容器内snap点的使用类型以及执行方式。

精确获取画廊中每一个滚动图片的snap点:

1
2
3
4
.gallery {
...
scroll-snap-type: mandatory;
}

mandatory属性确保滚动操作完成时,内容区域总是可以位于snap点。也就是说,每1000px.gallerydiv就会scroll-snap到一点。

Try it on Codepen

水平流体Snap Points

也可以使用百分比来定义流式snap点。如,我们将滚动容器的宽度设为90%,并且scroll-snap-points-x设置为repeat(100%)

1
2
3
4
5
6
.gallery {
...
width: 90%;
scroll-snap-points-x: repeat(100%);
scroll-snap-type: mandatory;
}

将snap点沿x轴设置,始于0px并重复于滚动容器100%的宽度区间内。

horz-scroll-snaps.gif

水平scroll snap points示例。

Try it on Codepen

垂直流式Snap Points

创建垂直snap点,我们将滚动容器的overflow-y设置为auto,overflow-x设置为hidden:

1
2
3
4
5
6
.gallery {
overflow-y: auto;
overflow-x: hidden;
width: 90%;
height: 48vw;
}

scroll-snap-points-y

使用scroll-snap-points-y属性,设置滚动容器内部垂直的snap点。既然滚动容器有一个流式高度,我们可以沿y轴设置snap点,始于0px,重复于滚动容器100%高度区间内:

1
2
3
4
5
.gallery {
...
scroll-snap-type: mandatory;
scroll-snap-points-y: repeat(100%);
}

接下来,使用更多的scroll-snap属性设置垂直滚动容器内的对齐方式:scroll-snap-coordinate以及scroll-snap-destination

scroll-snap-coordinate

在垂直滚动容器内将每一张图片水平居中,这时可以使用scroll-snap-coordinate属性,并将值设置为50% 50%(center):

1
2
3
4
img {
...
scroll-snap-coordinate: 50% 50%;
}

scroll-snap-destination

scroll-snap-destination属性定义了滚动容器内的位置 - 定义的所有snap点的对齐方式。将每一个snap与.gallery容器的中心对齐,需要将值设置为50% 50%(center):

1
2
3
4
5
6
.gallery {
...
scroll-snap-points-x: repeat(100%);
scroll-snap-type: mandatory;
scroll-snap-destination: 50% 50%;
}

vertical-scroll-snaps.gif

垂直scroll snap points的示例。

Try it on Codepen

浏览器的支持

目前为止,浏览器对CSS scroll snap points的支持限制在IE10+以及Firefox 39+。但是Safari 9好像也即将对其支持,你也可以在Chrome Candry内开启scroll snap points,Chrome浏览器允许在支持一些边缘属性前对其进行测试。

查看浏览器对scroll snap points的兼容性表格,获取浏览器的最新支持。

最后的一点想法

一旦浏览器可以稳定的支持CSS scroll snap points属性时,对于触控设备产生的意义将十分重大。如,我们可以在next/previous之间快速查看画廊中的每一张图片。

使用CSS创建scroll snap points意味着不再需要使用JavaScript或者导入一个多余的库定义滚动行为。并且scroll snap points属于硬件加速,保证了可以在浏览器中平滑的执行。