共计 6348 个字符,预计需要花费 16 分钟才能阅读完成。
在 CSS 标准 Scroll-linked Animations 中,推出了一个划时代的 CSS 性能。也就是 — The @scroll-timeline at-rule,直译过去就是 滚动工夫线。
本文,就将带大家一探到底,从入门到学会应用 CSS @scroll-timeline
。
何为 @scroll-timeline 滚动工夫线?
什么是 @scroll-timeline
滚动工夫线呢?
@scroll-timeline
可能设定一个动画的开始和完结由滚动容器内的滚动进度决定,而不是由工夫决定。
意思是,咱们能够定义一个动画成果,该动画的开始和完结能够通过容器的滚动来进行管制。
示意 DEMO
再系统性学习语法之前,咱们通过一个 DEMO,简略理解一下它的用法:
咱们首先实现一个 简略的字体 F 旋转动画:
<div id="g-box">F</div>
#g-box {
animation-name: rotate;
animation-duration: 3s;
animation-direction: alternate;
animation-easing-function: linear;
}
@keyframes rotate {
0% {transform: rotate(0);
}
100% {transform: rotate(360deg);
}
}
失常而言,它是这样一个简略的动画:
接下来,咱们把这个动画和 @scroll-timeline
相结合,须要把它搁置到一个可滚动的容器中:
<div id="g-content">
<div id="g-box">F</div>
</div>
#g-content {
width: 300px;
height: 170vh;
background: #999;
}
#g-box {
font-size: 150px;
margin: 70vh auto 0;
animation-name: rotate;
animation-duration: 3s;
animation-direction: alternate;
animation-easing-function: linear;
animation-timeline: box-rotate;
}
@keyframes rotate {
0% {transform: rotate(0);
}
100% {transform: rotate(360deg);
}
}
@scroll-timeline box-rotate {source: selector("#g-content");
}
这里,咱们实现了一个可滚动容器 #g-content
,它的高度是 170vh
,也就是可视界面高度的 1.7 倍,并且把 #g-box
容器搁置在一个间隔顶部 70vh
高度的中央:
有意思的来了,咱们设置的旋转动画不会主动开始,只有当咱们向下滚动的时候,动画才会开始进行,实际效果 Gif:
CodePen Demo — @scroll-timeline Demo
看到这里,大家应该可能了解 @scroll-timeline
的作用及含意了,它赋予了 CSS 可能基于滚动条的滚动去管制动画前进的能力! Amazing!!
@scroll-timeline 语法介绍
接下来,咱们先缓一缓,简略看一看 @scroll-timeline
的语法。
应用 @scroll-timeline
,最外围的就是须要定义一个 @scroll-timeline
规定:
@scroll-timeline moveTimeline {source: selector("#g-content");
orientation: vertical;
scroll-offsets: 0px, 500px;
}
其中:
-
source:绑定触发滚动动画的滚动容器
source: auto
:绑定到Document
,也就是全局 Windows 对象source: selector("id-selector")
,通过selector()
,内置一个#id
选择器,选取一个可滚动容器source: none
:不指的滚动容器
-
orientation:设定滚动工夫线的方向
orientation: auto
:默认为 vertical,也就是竖直方向的滚动orientation: vertical
:竖直方向的滚动orientation: horizontal
:程度方向的滚动orientation: block
:不太罕用,应用沿块轴的滚动地位,合乎书写模式和方向性orientation: inline
:不太罕用,应用沿内联轴的滚动地位,合乎书写模式和方向性
-
scroll-offsets:滚动工夫线的外围,设定在滚动的什么阶段,触发动画,可通过三种形式之一进行设置:
scroll-offsets: none
这意味着没有 scroll-offset 指定。- 由逗号分隔的 <length-percentage> 值列表确定。每个值都映射到 animation-duration。例如,如果 ananimation-duration 设置为 2s 且滚动偏移量为 0px, 30px, 100px,则在 1s 时,滚动偏移量将为 30px。
- 第三种确定滚动偏移量的办法是应用元素偏移量。这意味着能够指定页面内的元素,其地位决定了滚动工夫线以及要应用这些元素的哪个边缘。指定元素是应用 selector() 函数实现的,该函数接管元素的 id。边缘由关键字 start 或确定 end。可选的阈值的 0–1 可用于示意元素滚动中预期可见的百分比。
scroll-offsets
的了解会比拟艰难,咱们稍后详述。
在设定了一个 @scroll-timeline
之后,咱们只须要将它和动画绑定起来即可,通过 animation-timeline
:
@scroll-timeline moveTimeline {source: selector("#g-content");
orientation: vertical;
scroll-offsets: 0px, 500px;
}
div {
animation-name: move;
animation-duration: 3s;
animation-timeline: moveTimeline;
}
@keyframes move{
0% {transform: translate(0, 0);
}
100% {transform: translate(100%, 0);
}
}
应用 @scroll-timeline 实现滚动进度指示器
之前在 不堪设想的纯 CSS 滚动进度条成果 一文中,咱们介绍了一种应用突变实现的纯 CSS 滚动进度指示器成果:
该办法有些小小的瑕疵。其中一个就是当滚动间隔太短的时候,进度条右侧会有显著的斜边成果。
而有了 @scroll-timeline
之后,咱们终于能够将滚动和动画这两个元素绑定起来,再实现滚动进度指示器,就曾经十分轻松了:
<div id="g-container">
<p>... 文本内容...</p>
</div>
#g-container {width: 100vw;}
#g-container::before {
content: "";
position: fixed;
height: 5px;
left: 0;
top: 0;
right: 0;
background: #ffc107;
animation-name: scale;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-timeline: box-rotate;
transform-origin: 0 50%;
}
@keyframes scale {
0% {transform: scaleX(0);
}
100% {transform: scaleX(1);
}
}
@scroll-timeline box-rotate {
source: auto;
orientation: vertical;
}
- 咱们在页面最上方,通过一个伪元素,实现一个占满屏幕
100%
的5px
高的进度条。失常而言是这样:
- 通过设定一个
transform: scaleX(0)
到transform: scaleX(1)
的动画,并且将它与 body 的滚动相绑定,即可失去滚动指示器,成果如下:
残缺的代码,你能够戳这里:CodePen Demo – 应用 @scroll-timeline 实现滚动进度条
应用 scroll-offsets 准确管制动画触发机会
大家能够再看看下面的 Gif 图,都有一个问题,就是动画的开始工夫都是从滚动一开始就开始了,刚好在滚动完结时完结。那么如果我心愿动画在滚动的特定阶段触发,那该怎么办呢?
这里,就须要借助 scroll-offsets
,去更加准确的管制咱们的动画。
在滚动过程中,咱们能够将一个元素,划分为 3 个区域:
- 滚动过程中,从上方视线盲区,进入视线
- 滚动过程中,处于视线中
- 滚动过程中,从视线中,进入下方视线盲区
在这里,咱们就能够失去两个边界,上方边界,下方边界:
而对于高低两个边界,又会有两种状态。以上边界为例子,会有:
- 元素刚刚开始进入可视区
- 元素齐全进入可视区
对于这两种状态,咱们用 start 0
和 start 1
示意,同理,下方的边界也能够用 end 0
和 end 1
示意:
这里的 0 和 1 理论示意的是,元素滚动中预期可见的百分比。
有了这些状态值,配合 scroll-offsets
,咱们就能够准确管制滚动动画的触发工夫。
咱们设定一个从左向右并且随同透明度变动的动画,的看看上面几种状况:
- 滚动动画在元素从下方开始呈现时开始,齐全呈现后截止。
动画运行范畴:end 0
–> end 1
:
@keyframes move {
0% {transform: translate(-100%, 0);
opacity: 0;
}
100% {transform: translate(0, 0);
opacity: 1;
}
}
@scroll-timeline box-move {
source: auto;
orientation: "vertical";
scroll-offsets:
selector(#g-box) end 0,
selector(#g-box) end 1;
/* Legacy Descriptors Below: */
start: selector(#g-box) end 0;
end: selector(#g-box) end 1;
time-range: 1s;
}
#g-box {
animation-name: move;
animation-duration: 3s;
animation-fill-mode: both;
animation-timeline: box-move;
}
成果如下:
- 滚动动画在元素从下方齐全呈现时开始,在滚动到上方行将来到屏幕后截止:
动画运行范畴:end 1
–> start 1
:
// ...
@scroll-timeline box-move {
source: auto;
orientation: "vertical";
scroll-offsets:
selector(#g-box) end 1,
selector(#g-box) start 1;
/* Legacy Descriptors Below: */
start: selector(#g-box) end 1;
end: selector(#g-box) start 1;
time-range: 1s;
}
// ...
成果如下:
- 滚动动画在元素滚动到上方行将来到屏幕后开始,齐全来到屏幕后截止:
动画运行范畴:start 1
–> start 0
:
// ...
@scroll-timeline box-move {
source: auto;
orientation: "vertical";
scroll-offsets:
selector(#g-box) start 1,
selector(#g-box) start 0;
/* Legacy Descriptors Below: */
start: selector(#g-box) start 1;
end: selector(#g-box) start 0;
time-range: 1s;
}
// ...
成果如下:
把握 scroll-offsets
的用法是灵活运用滚动工夫线的要害,当然,在下面你还会看到 start: selector(#g-box) start 1
和 end: selector(#g-box) start 0
这种写法,这是标准历史遗留问题,最新的标准曾经应用了 scroll-offsets
去代替 start:
和 end:
的写法。
把上述 3 种状况放在一起,再比拟比拟:
残缺的代码,你能够戳这里:CodePen Demo – @scroll-timeline Demo | element-based offset
应用 @scroll-timeline 实现各类成果
在可能把握 @scroll-timeline 的各个语法之后,咱们就能够开始应用它发明各种动画成果了。
譬如如下的,滚动内容一直划入:
代码较长,能够戳这里,来自 bramus 的 Codepen CodePen Demo — Fly-in Contact List (CSS @scroll-timeline version)
甚至能够联合 scroll-snap-type
制作一些全屏滚动的大屏特效动画:
要晓得,这在以前,是齐全不可能利用纯 CSS 实现的。残缺的代码你能够戳这里:CodePen Demo — CSS Scroll-Timeline Split Screen Carousel
简而言之,任何动画成果,现在,都能够和滚动相结合起来,甚至乎是配合 SVG 元素也不例外,这里我还简略革新了一下之前的一个 SVG 线条动画:
残缺的代码你能够戳这里:CodePen Demo — SVG Text Line Effect | Scroll Timeline
@scroll-timeline 的实验室个性与个性检测
@scroll-timeline
虽好,目前仍处于实验室个性工夫,Chrome 从 85 版本开始反对,然而默认是敞开的。
兼容性如下(2022-03-07):
在最新的 chrome、Edge、Opera 能够通过浏览器配置开启该个性,Chrome 下开启该个性须要:
- 浏览器 URL 框输出
chrome://flags
- 开启
#enable-experimental-web-platform-features
美酒虽好,然而离齐全能用,浏览器大规模反对还须要期待一会,给工夫一点工夫吧!
个性检测
基于目前的兼容性问题,咱们能够通过浏览器的个性检测 @supports
语法,来渐进加强应用该性能。
个性检测的语法也非常简单:
@supports (animation-timeline: works) {
@scroll-timeline list-item-1 {source: selector(#list-view);
start: selector(#list-item-1) end 0;
end: selector(#list-item-1) end 1;
scroll-offsets:
selector(#list-item-1) end 0,
selector(#list-item-1) end 1
;
time-range: 1s;
}
// ...
}
通过 @supports (animation-timeline: works) {}
能够判断浏览器是否反对 @scroll-timeline
。
最初
目前对于 @scroll-timeline 的相干介绍还非常少,然而它确是可能扭转 CSS 动画的一个十分大的变革。随着兼容性的逐步遍及,将来势必会在 CSS 中占据一席之地。
本文到此结束,心愿对你有帮忙 :)
想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄
更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。
如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。