This article is published on my personal website, original link: A CSS-Only Scroll-Driven Animation Effect
First, let’s look at this simple example
Code:
You can also scroll down to see the effect directly.
|
|
Effect:
sticky: Sticky Layout
For front-end developers, this is not unfamiliar, so I’ll just briefly introduce it: position: sticky is a layout method between position:relative and position:fixed. When the parent element appears on the screen, it behaves like fixed, fixing itself on the screen. When the parent element goes out of the screen, it behaves like relative, following the normal document flow layout, being taken away by the parent container. Regarding how this case uses sticky to achieve similar element fixing effects, there is a simple demonstration on the right side of the effect example above, which can help with understanding. And this demonstration is also pure CSS.
All parent elements of a sticky element cannot set overflow:hidden, as this will invalidate sticky. If really needed, you can use overflow:clip instead.
animation-timeline: Scroll-Driven Animation
This is the core of this case. When this property is used on an element, the CSS animation defined by @keyframes will not play automatically, but will scroll according to the progress of the scrollbar. This property has two main values:
- animation-timeline: view() The animation starts when the element enters the viewport and ends when it leaves the viewport.
- animation-timeline: scroll() The animation plays when the element scrolls within the entire scroll container.
- animation-timeline: cont-name Named container, which will be discussed later.
animation-timeline: scroll()
scroll() is for the entire page and is relatively simple. It is used for effects related to global scrolling, such as article reading progress. Here I quote a picture from 前端侦探.
scroll() can take two parameters: scroller and axis
-
scroller The scroller parameter is used to specify the scroll container, with the default value being
nearest
. If set tonearest
, the nearest ancestor scroll container will be used. If set toroot
, the document viewport will be used as the scroll container. If set toself
, the element itself will be used as the scroll container. -
axis The axis parameter is used to specify the scroll axis, with the default value being
block
. If set toblock
, the block-level axis direction of the scroll container. If set toinline
, the inline axis direction of the scroll container. If set tox
, the element will scroll horizontally. If set toy
, the element will scroll vertically.
animation-range
If I don’t want the animation to play throughout the entire scrolling period, I can use the animation-range
property to set the start and end positions of the animation, with px
and %
units both acceptable.
For example:
|
|
This way, the animation will only play when the scroll container scrolls to the position of 0 to 100px, and will not play after 100px.
animation-timeline: view()
view() is relative to the position of the element and the viewport, and this case is based on view(). view() can also take two parameters: axis and inset
-
axis The axis parameter is used to specify the scroll axis, with the default value being
block
. If set toblock
, the block-level axis direction of the scroll container. If set toinline
, the inline axis direction of the scroll container. If set tox
, the element will scroll horizontally. If set toy
, the element will scroll vertically. -
inset The inset parameter is used to specify when the animation starts and ends, whether it starts when the element just peeks out or when the element completely enters the viewport, which is controlled by this property, somewhat similar to the role of
animation-range
above. inset accepts one or two values. When there are two values, they represent the start position and end position, withpx
and%
units both acceptable.
animation-timeline: cont-name
You may have noticed that with the above properties alone, we can only achieve animations where the parent element scrolls to drive the child element. What if I need to scroll one container to drive the animation of another sibling element? Then we need to rely on named containers.
It’s very simple to use. Just use an attribute scroll-timeline-name
on the scroll container.
|
|
In this way, when the .scroll
container is scrolled, the .animation
element will play the animation according to the scroll progress of the scroll container.