# 使用 sroll-snap-type 优化滚动

返回:优秀的开场

根据 CSS Scroll Snap Module Level 1 规范,CSS 新增了一批能够控制滚动的属性,让滚动能够在仅仅通过 CSS 的控制下,得到许多原本需要 JS 脚本介入才能实现的美好交互。

# 语法

 {
  scroll-snap-type: none | [ x | y | block | inline | both ] [ mandatory |
    proximity ]?;
}
1
2
3
4

举个例子,假设,我们希望一个横向可滚动容器,每次滚动之后,子元素最终的停留位置不是尴尬的被分割,而是完整的呈现在容器内,可以这样写:

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

li {
  scroll-snap-align: center;
}
1
2
3
4
5
6
7

上面 scroll-snap-type: x mandatory 中,x 表示捕捉 x 轴方向上的滚动mandatory 表示强制将滚动结束后元素的停留位置设置到我们规定的地方

如果是 y 轴方向的滚动也是一样的,只需要简单改一下 scroll-snap-type:

ul {
  scroll-snap-type: y mandatory;
}
1
2
3

# scroll-snap-type 中的 mandatory 与 proximity

  • mandatory: 通常在 CSS 代码中我们都会使用这个,mandatory 的英文意思是强制性的,表示滚动结束后,滚动停止点一定会强制停在我们指定的地方
  • proximity: 英文意思是接近、临近、大约,在这个属性中的意思是滚动结束后,滚动停止点可能就是滚动停止的地方,也可能会再进行额外移动,停在我们指定的地方

# scroll-snap-type: both mandatory

当然,还有一种比较特殊的情况是,scroll-snap-type: both mandatory,表示横向与竖向的滚动,都会同时进行捕捉,也是可以的:

# scroll-snap-align

使用 scroll-snap-align 可以简单的控制将要聚焦的当前滚动子元素在滚动方向上相对于父容器的对齐方式。

其需要作用在父元素上,可选值有三个:

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

p

# 不规则子元素滚动

如果子元素大小不一,也能有非常好的表现,使用 scroll-snap-align: center,使得不规则子元素在每次滚动后居于容器中间:

p

# 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>
1
2
3
4
5
6
.snap {
  overflow-x: auto;
  scroll-snap-type: y mandatory;
  scroll-padding-top: 30px;
}

li {
  scroll-snap-align: start;
}
1
2
3
4
5
6
7
8
9

# 废弃的 scroll-snap-points-x / scroll-snap-points-y

标准的发展过程,早年间的规范如今废除,这个了解一下即可,新标准现在是这几个,并且大部分浏览器已经兼容:

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