Scroll Timeline:动画跟着滚动条走
普通动画的「时间轴」是真实时间(DocumentTimeline)。animation-timeline 能把时间轴换成滚动进度:滚动条从头到尾 = 动画从 0% 到 100%。纯 CSS、不写一行
JS,就能做出「读到哪、进度条走到哪」的效果。浏览器支持情况见 caniuse。
1 · animation-timeline 与 animation-range
| 属性 | 取值 | 说明 |
|---|---|---|
animation-timeline |
none / auto(默认,即 DocumentTimeline) |
指定动画沿哪条时间轴推进 |
| 具名 timeline | --scroll-timeline-name |
引用某个具名的 scroll / view timeline |
| 匿名 timeline |
scroll() / view()
|
就地创建匿名时间轴 |
animation-range-start / -end |
normal(0%)/ percentage / length |
动画在时间轴上的起止位置 |
animation-range(简写) |
start end |
只给一个值时,第二个取 normal |
在 view-timeline 下,animation-range 还接受 cover / contain / entry / entry-crossing / exit / exit-crossing 等关键字,详见 View Timeline 一页。
animation 简写会重置 animation-timeline,所以 animation-timeline 一定要写在 animation 简写之后,否则会被重置回 auto。
2 · scroll-timeline-name 与 scroll-timeline-axis
| 属性 | 取值 | 说明 |
|---|---|---|
scroll-timeline-name
|
dashed-ident(如 --scroll) |
给某个有滚动条的元素命名,把它的滚动进度作为 timeline 提供出去 |
scroll-timeline-axis
|
block(默认)/ inline / x / y |
取哪个方向的滚动条 |
scroll-timeline(简写) |
--name axis |
axis 有默认值,可省略 |
3 · scroll():匿名 scroll-timeline
不必给元素命名,直接拿「某个祖先 scroller」的滚动进度做 timeline。关键字位置任意,例如 scroll(x nearest)。
| 关键字 | 含义 |
|---|---|
scroll(nearest)(默认) |
最近的可滚动祖先 |
scroll(root) |
文档根 |
scroll(self) |
元素自身 |
scroll(block|inline|x|y) |
指定轴 |
4 · 经典应用:整页阅读进度条 scroll(root)
scroll(root) 拿的是整个文档的滚动进度。配 position: fixed 的细条钉在视口顶部,就是最常见的「读到哪、条走到哪」阅读进度条——纯 CSS、零 scroll 监听。
.reading-progress {
position: fixed;
inset: 0 0 auto 0;
height: 5px;
transform-origin: 0 50%;
animation: read-grow auto linear;
animation-timeline: scroll(root);
}
@keyframes read-grow {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
两处要点:scroll-driven 下 duration 写 auto,表示动画覆盖整段时间轴;animation-timeline 写在 animation 简写之后,避免被重置。
这里用 transform: scaleX()(可下合成线程)而非动 width(每帧重排),理由见性能与取舍一页。
5 · timeline-scope:把 timeline 提升给更多元素用
*-timeline-name 默认只能作用于命名元素的后代。在它们的共同祖先上写 timeline-scope: --name,就能把作用域往上提,让更多兄弟或后代元素都能引用同一条 timeline。
下面框内的进度条与被滚动的框是兄弟关系(不是它的后代),靠 timeline-scope 把 --scroll-scope 提升到二者的共同祖先上,进度条才得以引用框的滚动进度。