CSS原生视差效果
摘要
使用滚动驱动动画时间线的CSS原生视差效果,提供了一个高性能且简单的工具类,无需JavaScript。
暂无内容
查看缓存全文
缓存时间: 2026/06/02 15:33
# 工具 | CSS原生视差效果
来源:https://dan-webnotes.com/posts/2026-06-02-css-native-parallax-effect/
2026年6月2日
视差效果由来已久,实现它的方法和库数不胜数。不过,最近出现了一种全新的 CSS 原生实现方式——借助 **CSS 滚动驱动动画时间线**(https://developer.mozilla.org/zh-CN/docs/Web/CSS/Guides/Scroll-driven_animations/Timelines)。以往的标准做法是在 JavaScript 中监听滚动事件,每帧重新计算位置,然后上下微调元素。而**滚动驱动动画**用 CSS 就把这一切处理完了。
使用 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%);
}
}
```
## # 时间线(https://dan-webnotes.com/posts/2026-06-02-css-native-parallax-effect/#the-timeline)
关键在于 `view-timeline-name`。它创建了一个**视图进度时间线**,这个时间线的进度是通过 `.parallax` 元素在滚动视口中穿过的距离来衡量的。当元素刚开始进入视口时,进度为 0%;当元素完全离开视口时,进度为 100%。`view-timeline-axis: block` 告诉它跟踪块级轴(在正常书写模式下即垂直轴)的运动。
在子元素上,`animation-timeline: --parallax-tl` 将动画的时钟从时间替换为该时间线。这样一来,`animation` 属性其余部分就各司其职了:
- `auto` 表示持续时间,此时持续时间来自时间线而非秒数
- `linear` 让滚动进度直接映射为移动
- `both` 让起始和结束帧在活动范围之外也能保持
> ⚠️ 注意:`animation-timeline` 这个简写属性并不属于 `animation` 简写的一部分,必须单独声明。此外,`animation-timeline` 必须在 `animation` 简写之后声明,因为简写属性会重置未包含的独立属性为初始值。
实际的动效由关键帧完成。使用默认偏移量时,当您滚动经过子元素时,它会从 `translate: 0 -20%` 滑到 `translate: 0 20%`。由于它以与周围容器不同的速度移动,因此能产生纵深感。
## # 缩放以避免空白区域(https://dan-webnotes.com/posts/2026-06-02-css-native-parallax-effect/#scaling-to-avoid-empty-spots)
子元素沿每个方向偏移自身高度的偏移百分比。如果子元素与容器大小完全相同,则将它向上或向下移动就会暴露出一个空白条。子元素需要被放大,才能有移动的余量。它需要在上下两端各多出偏移量的高度,因此总偏移量是两倍:
```css
scale: calc(1 + var(--parallax-offset, 20) * 2 / 100);
```
默认偏移量为 20 时,子元素会以其自身大小的 140% 渲染,多余的部分被容器的 `overflow: hidden` 裁剪,这样无论它在 ±20% 范围内移动到何处,总能有足够的内容覆盖整个盒子。
巧妙之处在于,`translate` 和 `scale` 都读取同一个 `--parallax-offset` 变量。调高偏移量可增强效果,而缩放也会随之匹配,从而自动保持覆盖正确。只需调整一个值,空白就不会再出现:
```css
```
最后一个元素是 `will-change: translate`,它提示浏览器该元素的 `translate` 即将改变,以便浏览器提前将其提升到独立图层。
## # 运动偏好(https://dan-webnotes.com/posts/2026-06-02-css-native-parallax-effect/#motion-preferences)
视差是一种与滚动绑定的运动,有些人可能不想看到它。尊重这一偏好是良好的实践,可以通过为设置了 `prefers-reduced-motion: reduce` 的人禁用动画来实现。在这种情况下,我们只需关闭动画和缩放:
```css
@media (prefers-reduced-motion: reduce) {
.parallax > * {
animation: none;
scale: 1;
}
}
```
### # 资源(https://dan-webnotes.com/posts/2026-06-02-css-native-parallax-effect/#resources)
- 使用滚动驱动动画实现元素滚动动效(https://developer.chrome.com/docs/css-ui/scroll-driven-animations)
- 滚动驱动动画时间线(https://developer.mozilla.org/zh-CN/docs/Web/CSS/Guides/Scroll-driven_animations/Timelines)
- scroll-timeline CSS 属性(https://developer.mozilla.org/zh-CN/docs/Web/CSS/Reference/Properties/scroll-timeline)
相似文章
@VincentLogic: 以前做前端,为了个加载动画,要么到处找 GIF,要么自己写 CSS 写到头秃。 最近看到这个 math-curve-loaders 开源库,完全是用数学公式生成的动效。 我看了一下,玫瑰曲线、李萨如曲线这些数学图形,动效极其优雅。纯 HT…
介绍了一个名为 math-curve-loaders 的开源前端库,利用数学公式(如玫瑰曲线、李萨如曲线)生成优雅的加载动画,纯 HTML+CSS 实现,零依赖,并带有可视化调试面板,可以实时调整参数并一键复制代码。
Show HN:一个CSS 3D引擎(无需WebGL)
PolyCSS 是一个 CSS 多边形网格库,能将 3D 模型渲染为真实的 HTML 元素(使用 CSS matrix3d),支持 OBJ/MTL、GLB 和 VOX 格式,可与 React、Vue 或原生 JavaScript 配合使用。
使用CSS进行抖动处理
本文演示如何使用CSS滤镜和SVG feTurbulence对图像应用抖动效果,以保持一致的视觉风格。
跨文档视图转换:无人提及的那些陷阱
一篇技术文章,解释CSS中跨文档视图转换的当前实现,涵盖已弃用的meta标签、常见陷阱(如4秒超时和宽高比变形)以及正确的选择加入方法。
Canvas 中的 HTML 演示
来自 Chrome DevRel 团队的 CSS 和 Web UI 演示合集,包括 Canvas 中的 HTML 演示。