能用原生CSS实现滚动深度驱动动画,前提是Chrome 115+/Edge 115+/Opera 101+等支持scroll-timeline的浏览器;需定义时间线、绑定animation-timeline、声明@keyframes和强制animation-duration,并注意root/容器滚动差异、animation-range语义及Safari兼容性兜底。

能用原生 CSS 实现滚动深度驱动的动画,前提是目标浏览器支持 scroll-timeline(Chrome 115+、Edge 115+、Opera 101+,Safari 尚未支持)。它不是“未来特性”,而是已落地的生产级能力——但必须明确:不加 polyfill 就无法在 Safari 或旧版 Chrome 中运行。
scroll-timeline 必须配合 animation-timeline 才生效
单独声明 scroll-timeline-name 或写 @scroll-timeline 规则本身不会触发任何动画。关键链路是:定义时间线 → 在元素上用 animation-timeline 绑定 → 动画必须有 @keyframes 和显式 animation-duration(哪怕只是占位)。
-
animation-duration是强制要求,即使值为1s也不会影响实际播放节奏——滚动距离才是真实时长 - 时间线名称区分大小写,
animation-timeline: --my-tl和scroll-timeline-name: --My-TL不匹配 - 滚动容器必须有明确的滚动行为(如
overflow-y: scroll),body默认可滚动,但若被重置过overflow就会失效
root 滚动 vs 容器内滚动:axis 和 source 的选择差异
用 scroll(root) 表示绑定到视口滚动,适合全页阅读进度条;用 scroll() 绑定到某个元素,则需确保该元素设置了 overflow 且内容溢出。两者对 scroll-timeline-axis 的处理不同:
-
scroll(root)默认按block轴(垂直滚动)计算,无需额外声明 - 自定义容器必须显式指定
scroll-timeline-axis: block或inline,否则时间线长度为 0 -
@scroll-timeline规则中若用source: selector(...),该选择器必须在 DOM 加载完成时存在,动态插入的容器不会自动纳入
animation-range 控制触发区间:entry-crossing 不等于 in-viewport
animation-range 决定动画从哪段滚动距离开始/结束,常用值如 entry-crossing 0% cover 100%。注意:entry-crossing 是基于 Intersection Observer 的“进入交叉点”,不是简单判断是否在视口内:
-
entry-crossing 0%指元素顶部刚接触视口顶部的瞬间 -
cover 50%表示元素完全覆盖视口高度的 50% 区域,不是“显示一半” - 若想实现“元素中心到达视口中心时开始动画”,要用
entry 50%+exit 50%组合 - 该属性目前仅在 Chrome/Edge 生效,Firefox 仍忽略
最易被忽略的是兼容性兜底:所有使用 scroll-timeline 的动画都应保留一份 JS + IntersectionObserver 的降级逻辑,尤其当产品需支持 Safari 用户时——不能只靠 @supports (animation-timeline: --tl) 切换样式,因为 Safari 完全不识别该特性,查询会直接返回 false。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











