Open bramus opened 8 months ago
Really sensible idea. Here's a supporting example that led me here:
https://codepen.io/nathanbabcock/pen/zYXmNwX
The goal is to add a gradient fade effect to the top/bottom of scrolling content as a subtle indication that there's more content in that direction. It should smoothly fade out when reaching the top or bottom of the scroll container (at an absolute pixel offset proportional to the length of the fade effect). Even with animation-range
, there's no way to accomplish this effect without double-nesting the content in two separate divs: one to track offset from the top, and one to track offset from the bottom.
Bramus' proposal above would make it possible to express all the logic underneath a single @keyframes
block.
After reading #10879, maybe we should allow <length-percentage>
inside <keyframe-selector>
in general, to open up the scroll-timeline
case as well?
@keyframes f {
0% { translate: 0% 0%; } /* ✅ Allowed */
150px { translate: 0% -100%; } /* ❌ Not allowed */
}
el {
animation-name: f;
animation-timeline: scroll();
}
(These are the keyframes for something like this shrinking header that animates using the animation-range
0px 150px
)
If we don’t want this extra addition, the current proposal can already work if we enable scroll
to target the full range of the ScrollTimeline
(see request here):
@keyframes f {
scroll 0% { translate: 0% 0%; } /* ✅ Allowed */
scroll 150px { translate: 0% -100%; } /* ❌ Not allowed */
}
el {
animation-name: f;
animation-timeline: scroll();
}
Feedback from @flackr, @fantasai, @tabatkins, @ydaniv, @birtles, etc would be appreciated here :)
Since we already allowed range names in there, might as well allow length-percentage too. The whole point of that was to allow specifying points on the timeline directly as selectors, so makes sense to allow anything that can select a point on the timeline.
The problem
With Scroll-Driven Animations, authors often want to run animations offsetted against one of the segment edges. For example, to run an animation up to "100px from the start of the range". For this, authors can do calculations in keyframe offsets, e.g.
animation-range: entry 0% entry calc(0% + 100px);
.While this syntax works perfectly fine, it is not allowed everywhere. Depending on which keyframes format authors use, they can or can’t do calculations.
@keyframes
that include range information: ❌ Not allowedThis leads to frustration, as recently expressed by Matthew Perry on Twitter:
I think we should close this gap, and allow calculated keyframes across the board.
Performing calculations in the offsets
Web Animations API
If they want to – and they often do – authors can also do calculations in the
offset
value. When passing in keyframes as an object, they can adjust the values forrangeStart
and/orrangeEnd
:However, when passing in an array of objects as the keyframes, it is not accepted.
In both snippets above, authors get back this error:
CSS Animations
Looking at the CSS variant of SDA, it’s similar there: when using
animation-range
an author can do calculations, but when creating a set of keyframes with@keyframes
they can not.The Cause
In both cases (CSS or WAAPI), this is because of the syntax of keyframe selectors. As per spec, the offsets are limited to
<percentage>
s when combined with a<timeline-range-name>
:This in contrast to
animation-range-start
andanimation-range-end
which do accept lengths (spec):Proposed Solution
Allow
<length-percentage>
– instead of only<percentage>
– in<keyframe-selector>
when combined with<timeline-range-name>
.By allowing
<length-percentage>
, authors can perform these calculations across the board, independent of which format they use to create their animation. The proposed new syntax is this:As a result, the failing code snippets listed above will start to work fine.