CSS Scroll Snap 的工作模式

1,972 阅读4分钟

原文地址: blog.usejournal.com/css-scroll-…
译文地址:github.com/xiao-T/note…
本文版权归原作者所有,翻译仅用于学习。


还记不记得,为了在页面上实现优雅的滚动效果(gallery, slide 等等)需要借助 JS 的那些日子?送走 JS,投入 CSS Scroll Snap 怀抱吧。

很久以前,当时 CSS 还处于第一阶段,我们就介绍过 CSS Scroll Snap,它可以让滚动的元素紧贴容器的边界。但是,只有 Firefox 支持。到了现在,**所有的浏览器**都得到了支持。我们来拥抱它,放弃 JS,实现纯 CSS 的滚动效果。

它有什么好处?

假设,我们需要在页面上对比一些内容。我们需要某一个项目和一个列表中所有的项目一一对比。我们不知道列表的长度,但是,我们想把整个列表中的项目和需要对比的项目并排在一起。列表太长,需要滚动(假设是在 X 轴滚动),每当页面滚动时,我们想看到的是每个项目完整的尺寸,而不是一部分。

在没有这个 CSS 属性的情况下,如果,我们需要滚动列表,必须小心翼翼的,尽可能的让某一元素贴近容器的边界。但是,通过利用这个 CSS 属性,我们只需滚动元素的 50%,然后,剩下的交给浏览器处理就好。

如果,你在的移动设备上,向左、向右、向上或者向下滚动一点。整个屏幕将会滚动到”下一页“(如果,有的情况下),你并不需要滚动整个页面。这将是这个属性最好的演示场景。

Scroll snap type

我们定义了 container 有一组 scrolling items 元素,通过设置 CSS Scroll Type 属性,让它们在滚动时紧贴容器的边界。我们有以下几个值可选:none, x, y, block, inline 或者 both

codepen.io

这些选项之间的区别是:

  • none — 不需要紧贴边界

  • x — 紧贴 x 轴边界

  • y — 紧贴 y 轴边界

  • block — 紧贴 block 轴(逻辑属性)— 垂直轴(等同于 Y 轴)

  • inline — 紧贴 inline 轴(逻辑属性)— 水平轴(等同于 X 轴)

  • both — 紧贴 x 和 y 轴

scroll-snap-type 中还有另外一个属性需要设置,它的值包括:

  • mandatory
  • proximity

简单的理解就是:值为 mandatory 时,当元素滚动到自身宽度(x/inline 轴)或者高度(y/block 轴)51% 时会自动的滚动,然后,值为 proximity 时,滚动需要接近整个元素的大小才会自动贴近边界。

译者注:对比了两种效果,没看出有什么差别。MDN上的翻译也比较难以理解😂

scroll-snap-type 的语法和选值如下所示:

scroll-snap-type: none | [ x | y | inline | block ] [ mandatory | proximity ];

现在,我们知道了滚动元素**在哪紧贴边界,接下来,我们可以在滚动元素上设置 scroll-snap-align 属性来决定如何**紧贴边界。

修复 iOS 的问题

感谢 Denys Mishunov 为 iOS 用户提供了这个修复方案

为了支持 iOS 用户,只需添加下面一行代码

-webkit-overflow-scrolling: touch;

因此,我们的代码应该是这个样子:

.foo {
     scroll-snap-type: x mandatory;
     -webkit-overflow-scrolling: touch;
}

Scroll snap align

我们可以定义滚动元素如何紧贴边界,有以下几个选择:start, centerend

为了实现相应的效果,我们需要给每个滚动元素定义 “scroll-snap-align”。

如果,我们给滚动的元素定义:“scroll-snap-align: start”,那么它将会紧贴容器的边界开始位置(根据我们选择的轴来定义)

如果,我们声明了 “scroll-snap-align: center;”,那么滚动元素将会在容器中间显示,边界线围绕在元素的周围—就像你在上图中看到的一样。

接下来的三示例分别对应这 scroll-snap-type 的三个不同选值:X, YBoth — 它们的 scroll-snap-align 值都为 "start""center"。

X 轴

Y 轴

both

Scroll margin / Scroll padding

scroll-padding 和 scroll-margin 就相当于 padding / margin。可以控制滚动元素和边界之间的留白。

例如:设置 “scroll-padding: 10px;”,滚动元素跟容器边界之间会有个 10px 的留白。

目前,这些属性并没有完全支持

Browser support

根据 “caniuse” 记录可以知道,现在所有的浏览器都已经支持这一属性

  • IE / Edge 需要前缀 -ms-

  • Firefox 中可以用旧的语法

最后一个示例,你将会看到一个可以垂直/水平滚动的幻灯片效果。

slides demo

总结

  • CSS 属性更加容易使用

  • 我们可以快速轻松的创建滚动图库、幻灯片、全屏滚动等效果

  • 在我们看来,依旧会有个小问题。如果,其中一个元素比容器还要大,我们并不能看到它的全部—滚动的时候将会跳转到下一个元素。