CSS滚动视差

html-css010

CSS滚动视差,第1张

何为滚动视差

    视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。 作为网页设计的热点趋势,越来越多的网站应用了这项技术。

    通常而言,滚动视差在前端需要辅助 Javascript 才能实现。但是使用background-attachment也可以做到这样的效果。

    要了解background-attachment的作用可以参考我的另一篇关于它的简单介绍:

    什么是background-attachment

    使用background-attachment: fixed实现滚动视差

    首先,我们使用background-attachment: fixed来实现滚动视差。fixed 此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。

    这里的关键在于,即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。也就是说, 背景图从一开始就已经被固定死在初始所在的位置。

    我们使用,图文混合排布的方式,实现滚动视差,HTML 结构如下, .g-word表示内容结构,.g-img表示背景图片结构 :

关键 CSS:

效果如下:

嗯?有点神奇,为什么会是这样呢?可能很多人会和我一样,第一次接触这个属性对这样的效果感到懵逼。

我们把上面background-attachment: fixed注释掉,或者改为background-attachment: local,再看看效果:

这次,图片正常跟随滚动条滚动了,按常理,这种效果才符合我们大脑的思维。

而滚动视差效果,正是不按常理出牌的一个效果,重点来了:

当页面滚动到图片应该出现的位置,被设置了background-attachment: fixed的图片并不会继续跟随页面的滚动而跟随上下移动,而是相对于视口固定死了。

好,我们再来试一下, 如果把所有.g-word内容区块都去掉 ,只剩下全部设置了background-attachment: fixed的背景图区块,会是怎么样呢?

效果如下:

结合这张 GIF,相信能对background-attachment: fixed有个更深刻的认识,移动的只有视口,而背景图是一直固定死的。

综上,就是 CSS 使用background-attachment: fixed实现滚动视差的一种方式,也是相对而言比较容易的一种。

参考文章: 滚动视差?CSS 不在话下

前情提要:本篇文章已经默认你已经彻底了解perspective和translateZ的含义与用法,如果尚未了解,我推荐你看 css3系列之详解perspective

是不是比起普通网站多了一层酷炫?想知道如何实现吗?接下来我们进入part2。

步骤:

1.建立一个容器元素,设置 overflow-y: scroll 使其可以滚动(同时可能需要 overflow-x: hidden)。

2.对于上面的元素, 我们会应用一个 perspective 值,然后设置 perspective-origin 到 top left, 或者 0 0。

3.对上面元素的子元素应用一个在 Z 轴的变换,然后把它们还原回来以实现视差效果,而没有影响它们在屏幕上的大小。

这种方案下的css和html:

是不是很简单?

现在的你已经写出基本的视差滚动动画了!但是perspective和translateZ是怎么影响滚动速度的?还有scale,为什么这里设置的是3?想知道吗?那么接下来进入part3

这里把scale设为S,pespcetive->P,translateZ->D // 注意D一般是负值

那么有公式 S=(P-D)/P ,

这个公式怎么来的?这其实就是一个简单的相似三角形

划红线的地方的比例就是1:3,那么你只需要在原来的基础上放大3就可以让图形变回原来的比例,这里的1就是P,2就是D,那么很容易发现图形的缩小比例是P/(P-D),想放大回来?倒置这个缩小比例即可,我们便得到了S=(P-D)/P

现在我们已经靠scale属性让图形变回了原来的大小,似乎一切都恢复了原状,但有一个东西,它变了,便是滚动速度,滚动速度和上面的缩小比例是完全一致的,以如下数据为例

不看scale,这里的缩小比例是1/3,那么由于css机制,它的滚动速度也会变成原来的1/3。即使添加了scale属性,它的滚动速度依然不变还是原来的1/3。

现在让我们来总结性质:

父元素设置perspective,子元素设置 translateZ(-2px),那么无论是否有scale属性,

则有

PS:如果不设置 translateZ,或者 translateZ(0),那么对应D=0,所以有缩小比例=滚动速度比=(P/P-0)=1:1,即相对于原来的滚动速率不变。

为了方便读者尝试,我码了一个小小的demo,你可以任意更改属性来验证上面的结论!

参考文献

Performant Parallaxing : https://developers.google.com/web/updates/2016/12/performant-parallaxing

[杨耿]css3系列之详解perspective:

https://www.cnblogs.com/yanggeng/p/11285856.html

CSS3的动画的优点:

1.在性能上会稍微好一些,浏览器会对CSS3的动画做一些优化(比如专门新建一个图层用来跑动画)

2.代码相对简单

但其缺点也很明显:

1.在动画控制上不够灵活

2.兼容性不好

3.部分动画功能无法实现(如滚动动画,视差滚动等)

JavaScript的动画正好弥补了这两个缺点,控制能力很强,可以单帧的控制、变换,同时写得好完全可以兼容IE6,并且功能强大。但想想CSS动画的transform矩阵是C++级的计算,必然要比javascript级的计算要快。另外对库的依赖也是一个很让人头疼的问题。

所以,对于一些复杂控制的动画,使用javascript会比较靠谱。而在实现一些小的交互动效的时候,就多考虑考虑CSS吧。