In the CSS specification Scroll-linked Animations , an epoch-making CSS feature was introduced. That is -- The @scroll-timeline at-rule, which literally translates to scrolling timeline .
In this article, I will take you to find out, from getting started to learning to use CSS @scroll-timeline
.
What is @scroll-timeline scrolling timeline?
What is @scroll-timeline
rolling timeline?
@scroll-timeline
Ability to set the start and end of an animation to be determined by the scrolling progress inside the scroll container, rather than by time.
Meaning, we can define an animation effect whose start and end can be controlled by scrolling the container .
Indicate DEMO
Before systematically learning grammar, let's take a brief look at its usage through a DEMO:
We first implement a simple font F rotation animation :
<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);
}
}
Normally, it's a simple animation like this:
Next, we combine this animation with @scroll-timeline
, which needs to be placed into a scrollable container:
<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");
}
Here, we implement a scrollable container #g-content
whose height is 170vh
, which is 1.7 times the height of the visual interface, and place the #g-box
container at a height of 70vh
from the top:
Interestingly, the rotation animation we set will not start automatically, only when we scroll down, the animation will start, the actual effect Gif:
CodePen Demo -- @scroll-timeline Demo
Seeing this, everyone should be able to understand the role and meaning of @scroll-timeline
, It gives CSS the ability to control the animation based on the scrolling of the scroll bar! Amazing! !
Introduction to @scroll-timeline syntax
Next, let's take a moment and take a brief look at the syntax of @scroll-timeline
.
Using @scroll-timeline
, the most important thing is to define a @scroll-timeline
rule:
@scroll-timeline moveTimeline {
source: selector("#g-content");
orientation: vertical;
scroll-offsets: 0px, 500px;
}
in:
source: Bind the scroll container that triggers the scroll animation
source: auto
: bind toDocument
, the global Windows objectsource: selector("id-selector")
, viaselector()
, with a built-in#id
selector to select a scrollable containersource: none
: scroll container not referring to
orientation: Set the direction of scrolling the timeline
orientation: auto
: The default is vertical, which is vertical scrollingorientation: vertical
: vertical scrollingorientation: horizontal
: horizontal scrollingorientation: block
: less commonly used, uses scroll position along block axis, conforms to writing mode and directionalityorientation: inline
: less common, uses scroll position along inline axis, conforms to writing mode and directionality
scroll-offsets: The core of scrolling the timeline, is set at what stage of scrolling to trigger the animation , which can be set in one of three ways:
scroll-offsets: none
This means that no scroll-offset is specified.- Determined by a comma-separated list of <length-percentage> values. Each value maps to animation-duration . For example, if animation-duration is set to 2s and the scroll offset is 0px, 30px, 100px, at 1s the scroll offset will be 30px.
- A third way to determine scroll offsets is to use element offsets. This means that elements within the page can be specified whose positions determine the scrolling timeline and which edge of those elements to use. Specifying an element is done using the selector() function, which receives the element's id. The edge is determined by the keyword start or end. An optional threshold of 0–1 can be used to represent the percentage of elements expected to be visible in scrolling.
scroll-offsets
will be more difficult to understand, we will describe in detail later.
After setting a @scroll-timeline
, we only need to bind it to the animation, through 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);
}
}
Scrolling progress indicator using @scroll-timeline
Earlier in the Incredible Pure CSS Scrolling Progress Bar Effect , we introduced a pure CSS scrolling progress indicator effect implemented using gradients:
This method has some minor flaws. One of them is that when the scrolling distance is too short, the right side of the progress bar will have an obvious bevel effect.
And with @scroll-timeline
, we can finally bind the two elements of scrolling and animation, and then implement the scrolling progress indicator, it is very easy:
<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;
}
- At the top of the page, we use a pseudo element to implement a
5px
high progress bar that fills the screen100%
. Normally this is:
- By setting an animation from
transform: scaleX(0)
totransform: scaleX(1)
and binding it to the scrolling of the body, you can get the scroll indicator, the effect is as follows:
For the complete code, you can click here: CodePen Demo - Scrolling progress bar using @scroll-timeline
Use scroll-offsets to precisely control animation trigger timing
You can look at the Gif image above, there is a problem, that is, the start time of the animation starts from the beginning of the scroll, and ends just at the end of the scroll. So what if I want the animation to fire at a specific stage of scrolling?
Here, we need to use scroll-offsets
to control our animation more precisely.
During the scrolling process, we can divide an element into 3 areas:
- During the rolling process, enter the field of vision from the blind spot of the upper field of view
- During scrolling, in view
- During the scrolling process, from the field of vision, enter the blind spot of the lower field of vision
Here, we can get two boundaries, the upper boundary and the lower boundary:
For the upper and lower boundaries, there will be two states. The above boundary is an example, there will be:
- The element has just started to enter the viewable area
- The element fully enters the viewable area
For these two states, we use start 0
and start 1
represent, similarly, the lower boundary can also be represented by end 0
and end 1
:
The 0s and 1s here actually represent the percentage of expected to be visible in the scroll of elements.
With these state values, together with scroll-offsets
, we can precisely control the trigger time of the scroll animation.
Let's set an animation from left to right and change with transparency. Let's take a look at the following situations:
- The scroll animation starts when the element begins to appear from below and ends when it appears completely.
Animation running range: 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;
}
The effect is as follows:
- The scroll animation starts when the element is fully visible from the bottom and ends when the element is scrolled to the top and is about to leave the screen:
Animation running range: 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;
}
// ...
The effect is as follows:
- The scroll animation starts when the element is scrolled to the top and is about to leave the screen, and ends when it completely leaves the screen:
Animation running range: 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;
}
// ...
The effect is as follows:
Mastering the usage of scroll-offsets
is the key to flexible use of the scrolling timeline. Of course, you will also see the writing methods of start: selector(#g-box) start 1
and end: selector(#g-box) start 0
, which are left over from the history of the specification. The latest specification has used scroll-offsets
to replace the writing methods of start:
and end:
. .
Put the above three cases together and compare them:
For the complete code, you can click here: CodePen Demo - @scroll-timeline Demo | element-based offset
Use @scroll-timeline to achieve various effects
After we can grasp the various syntaxes of @scroll-timeline, we can start to use it to create various animation effects.
For example, the scrolling content continues to enter:
The code is longer, you can click here, Codepen 162257541b0512 from CodePen Demo -- Fly-in Contact List (CSS @scroll-timeline version)
You can even combine scroll-snap-type
make some full-screen scrolling large-screen special effects animations:
You know, this was completely impossible to achieve with pure CSS before. You can click here for the complete code: CodePen Demo -- CSS Scroll-Timeline Split Screen Carousel
In short, any animation effect can now be combined with scrolling, even with SVG elements. Here I simply modified a previous SVG line animation:
You can click here for the complete code: CodePen Demo -- SVG Text Line Effect | Scroll Timeline
Lab characterization and characterization testing for @scroll-timeline
Although @scroll-timeline
is good, it is still in the laboratory feature time. Chrome supports it from version 85, but it is turned off by default.
Compatibility is as follows (2022-03-07):
In the latest chrome, Edge, and Opera, you can enable this feature through browser configuration. To enable this feature under Chrome, you need:
- Enter
chrome://flags
in the browser URL box - Open
#enable-experimental-web-platform-features
Although the wine is good, it will take a while for the browser to support large-scale support before it is fully usable. Give it some time!
Feature detection
Based on the current compatibility issues, we can use the feature of the browser to detect @supports
syntax to progressively enhance the use of this function.
The syntax for feature detection is also very simple:
@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;
}
// ...
}
Through @supports (animation-timeline: works) {}
, you can judge whether the browser supports @scroll-timeline
.
finally
There is very little introduction about @scroll-timeline, but it is a very big innovation that can change CSS animation. As compatibility grows in popularity, it's bound to have a place in CSS in the future.
This concludes this article, I hope it helps you :)
If you want to get the most interesting CSS information, don't miss my official account -- iCSS front-end anecdotes 😄
More wonderful CSS technical articles are summarized in my Github -- iCSS , which will be updated continuously. Welcome to click star to subscribe to the collection.
If you have any questions or suggestions, you can communicate more. Original articles are limited in writing and knowledge. If there are any inaccuracies in the article, please let me know.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。