CSS滚动驱动动画实战:告别JS,用几句声明实现视差滚动和进度指示器

2026-06-20 0 985

上个月在一个产品介绍页里,产品经理要求加上滚动时的进度条、首屏标题随滚动淡入、还有几组视差背景。按照以前的做法,我得先监听scroll事件,计算滚动偏移量,再用requestAnimationFrame更新元素的样式或CSS变量。代码写了一堆,还得小心性能,在低端设备上滚动往往会掉帧。

后来把整套逻辑迁移到了CSS滚动驱动动画上——进度条只需两行声明,视差效果交给了scroll-timeline,元素入场动画用view-timeline搞定。整个产品页的JavaScript滚动监听几乎被删光了,滚动帧率反而稳在了60fps。这篇文章就把这些实操技巧完整端出来,看完你也能在项目里立刻上手。

核心概念:时间线从滚动容器来

CSS动画通常依赖时间轴——默认是钟表时间(animation-durationanimation-delay)。而滚动驱动动画让动画的进度由滚动容器的滚动偏移量(或元素在视口中的可见性)来决定。

主要有两种函数定义这种时间线:

  • scroll() —— 基于滚动容器的滚动进度,从0%滚到100%对应动画的0%到100%。
  • view() —— 基于元素相对于视口的出现与消失,比如元素开始进入视口到完全离开视口,控制动画的进行阶段。

两者都需要在animation-timeline属性中指定,取代传统的animation-duration作为进度来源。同时,你仍然可以使用@keyframes定义动画帧。

案例一:全站滚动进度条

很多阅读型网页顶部会有一条细线,随滚动不断增长,直观显示当前文章读到哪了。用CSS实现,甚至不需要任何JavaScript。

先写一个HTML结构,放置进度条容器:

<body>
  <div class="progress-bar"></div>
  <!-- 页面其他内容 -->
</body>

CSS核心代码:

.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 4px;
  background: linear-gradient(90deg, #4facfe, #00f2fe);
  /* 指定动画由页面滚动驱动,沿着纵向滚动 */
  animation: grow-progress linear;
  animation-timeline: scroll(root);
  transform-origin: left center;
}

@keyframes grow-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

这里 animation-timeline: scroll(root) 表示以根元素(html)的滚动进度作为时间线。滚动条从顶部滚到底部,动画自动从0%走到100%,进度条也就从左到右填满整屏。不需要监听任何事件,也无需手动计算百分比。

如果希望进度条用在某个特定的滚动容器(比如一个带滚动条的区域),可以指定scroll(nearest)scroll(self),甚至可以自定义一个具名滚动时间线。

案例二:视差滚动背景

以前做视差效果,要么用translateY配合JavaScript,要么用多个background-attachment: fixed去模拟。现在可以利用滚动进度直接驱动背景偏移。

设想一个场景:首屏大图背景,随着用户向下滚动,背景缓慢上移,形成深度感。

<header class="hero">
  <h1>发现自然之美</h1>
</header>
<section>...长内容...</section>

CSS如下:

.hero {
  height: 100vh;
  background-image: url('mountain.jpg');
  background-size: cover;
  background-position: center;
  animation: parallax-move linear;
  animation-timeline: scroll(root);
}

@keyframes parallax-move {
  from { background-position-y: 0%; }
  to   { background-position-y: 40%; } /* 背景以不同速度移动 */
}

滚动页面时,background-position-y 从0%变化到40%,产生视差效果。因为动画由根滚动驱动,不会有任何JS干预,而且浏览器可以将此效果提升到合层线程,即使主线程忙着加载图片,滚动依然顺滑。

案例三:元素进入视口时淡入上移(view-timeline)

很多营销页面喜欢让卡片、标题在滚动到可见区域时才出现并上浮。这曾是各种“scroll animation”库的主战场,现在CSS的view()函数可以单挑。

先准备一组卡片:

<div class="card-container">
  <div class="card">...</div>
  <div class="card">...</div>
  <div class="card">...</div>
</div>

为了给每张卡片添加进出场动画,我们使用view-timeline

.card {
  opacity: 0;
  transform: translateY(40px);
  animation: fade-in-up linear;
  /* 以自身在视口中的可见性作为时间线,覆盖从进入10%到离开90%的过程 */
  animation-timeline: view(block 10% 90%);
  animation-range: entry 0% cover 30%; /* 可进一步精确控制动画范围 */
}

@keyframes fade-in-up {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

这里 view(block 10% 90%) 定义了时间线的开始点为元素刚进入视口底部10%(即元素顶部距离视口底部10%位置时),结束点为元素离开视口90%(元素底部距离视口顶部90%位置时)。animation-range 则进一步限定了动画发生的区间:从元素进入视口(entry)到覆盖30%视口高度的位置,动画就播放完毕,这样卡片在完全进入视口前就已经淡入到位,看起来非常自然。

当页面滚动时,每张卡片会根据自身的可见性独立播放动画,完全不用一行JS。

几个容易踩到的细节

  • 滚动容器必须可滚动:如果使用scroll(nearest)但祖先容器没有滚动条,动画将没有进度。确保指定了正确的滚动源。
  • 与正常动画叠加:如果同时设置了animation-durationanimation-timeline 会覆盖它,但你可以使用animation-timeline 结合 animation-range 来细化起止位置,而不需要duration
  • 浏览器支持:Chrome 115+、Edge 115+、Safari 17.4+、Firefox 130+(需开启 layout.css.scroll-driven-animations.enabled)。生产环境建议使用 @supports (animation-timeline: scroll()) 进行检测,并提供降级方案。
  • 性能:由于动画绑定在合成属性(如transformopacity)上,浏览器可以在合成线程上运行,不需要回流或重绘。尽量避免在滚动动画里使用widthmargin等布局属性。

比JavaScript更好维护的原因

过去用scroll事件驱动动画,往往需要计算各种高度、判断元素可见性,代码散布在多个地方。CSS滚动驱动动画将动画的定义与实际滚动行为绑定于一处,便于整体管理。样式与行为都在CSS内,视图与控制完全分离,而且滚动动画天然支持“反向”播放——当你往回滚动,动画会倒带回退,这点在JS里做起来很繁琐,而CSS自动实现。

总结

滚动驱动动画给CSS赋予了更贴合人眼感知的表达能力。进度条、视差、入场动画,这些原本需要脚本护持的动态效果,现在可以像写静态样式一样轻松组织。而且因为省去了监听与计算,移动端的滚动手感往往比JS方案更顺畅。

如果你正在做一个偏向内容展示的产品页面,不妨把这几个案例拿去试,从删除那一大堆scroll事件监听开始,体会纯粹由样式驱动的滚动交互——少即是多。

CSS滚动驱动动画实战:告别JS,用几句声明实现视差滚动和进度指示器
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:
本站资源有的来自互联网收集整理,本站纯免费分享提供学习使用,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,免费开源项目不代表完全可商用,若商业用途请先咨询开发企业能否商用,否则产生的一切后果将由下载用户自行承担。
原创板块未经允许不得转载,否则将追究法律责任。

淘吗网 css CSS滚动驱动动画实战:告别JS,用几句声明实现视差滚动和进度指示器 https://www.taomawang.com/web/css/2254.html

常见问题

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务