CSS 原生视差效果
2026年6月2日,视差效果有着悠久的历史,虽然有无数种方法和库可以实现它们,但最近使用CSS滚动驱动的动画时间轴使得一种新的CSS原生方法成为可能。通常的方法是在JavaScript中使用滚动事件监听器,在每一帧中重新计算位置并对元素进行上下移动。滚动驱动的动画用CSS处理了所有这些。使用CSS处理视差动画有几个优点:性能应该更好,因为它是在主线程之外运行的,但我最喜欢的部分是整个过程变得简单,只需一个小的声明性样式块,就可以通过一个实用类应用。以下是该类的完整代码: .parallax { view-timeline-name: --parallax-tl; view-timeline-axis: block; overflow: hidden; & > * { scale: calc(1 + var(--parallax-offset, 20) * 2 / 100); animation: parallax auto linear both; animation-timeline: --parallax-tl; animation-range: cover; will-change: translate; } } @keyframes parallax { from { translate: 0 calc(var(--parallax-offset, 20) * -1%); } to { translate: 0 calc(var(--parallax-offset, 20) * 1%); } } # 时间线 诀窍在于 view-timeline-name。它创建了一个视图进度时间轴,该时间轴的进度通过.parallax元素在滚动区域中移动的距离来测量。当元素开始进入视口时,读取0%,完全离开时读取100%。 view-timeline-axis: block指示它沿块轴(在正常书写模式下是垂直轴)跟踪移动。在子元素上,animation-timeline: --parallax-tl将动画的时钟从时间切换到该时间轴。从这里开始,动画线的其余部分依次到位:auto作为持续时间,因为持续时间来自时间轴而不是以秒为单位的数字,linear以便于滚动进度直接映射到移动位置,同时保持起始和结束帧在活动范围之外 ⚠️ 注意:animation-timeline 长属性不是动画缩写的一部分,必须单独声明。此外,animation-timeline必须在动画缩写之后声明,因为缩写将会将未包含的长属性重置为其初始值。关键帧负责实际的工作。使用默认偏移量,子元素在滚动经过时从translate: 0 -20%滑动到translate: 0 20%。由于它与周围容器的移动速度不同,你会感受到那种深度感。# 伸缩以避免空隙 子元素在每个方向上的位移可达自身高度的偏移百分比,因此如果子元素的大小恰好与其容器相同,上下移动将暴露出一条空白区域。子元素需要放大,以便有空间可以移动。它需要以上下的偏移量总共的额外高度:scale: calc(1 + var(--parallax-offset, 20) * 2 / 100); 使用的默认偏移量为20,子元素呈现为其大小的140%,多余的部分被容器上的overflow: hidden剪裁,并且无论在±20%的移动范围内何处,总是有足够的内容覆盖盒子。精妙之处在于平移和缩放都读取相同的--parallax-offset变量。将偏移量调高以获得更强的效果,缩放也随之增长,因此覆盖始终保持正确。一个要调整的值,空隙不会回来了:<div class="parallax" style=" --parallax-offset: 30; "> <img src="…" /> </div> will-change: translate是最后一块,它提示该元素的translate即将发生变化,以便浏览器提前将其提升到自己的图层。# 动作偏好 视差是一种与滚动关联的运动,有些人可能不希望有这种效果。尊重这一点是一个好的做法,对于任何设置了prefers-reduced-motion: reduce的人禁用动画。在这种情况下,我们可以简单地关闭动画和缩放:@media (prefers-reduced-motion: reduce) { .parallax > * { animation: none; scale: 1; } } # 资源 在滚动时使用滚动驱动动画为元素添加动画 滚动驱动的动画时间轴 scroll-timeline CSS属性
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡