-
Notifications
You must be signed in to change notification settings - Fork 707
[css-animations-2] Add animation-trigger for triggering animations when an element is in a timeline's range #8942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
also ping @birtles |
I'm just curious about what the discussion was here. I know in the very very early days of the scroll-driven animations spec we have scroll triggers which would have been awesome--basically like declarative intersection observer so you could trigger transitions or even just static changes. The main problem was just that you couldn't easily implement them such that they run on the compositor. I think they were probably the same thing as
Fill modes are tricky. They don't compose very well and we had to introduce the whole effect replacing mechanism just to prevent them from leaking memory. At times we've talked about deprecating them if we could. They might be the right primitive here, but just as a knee-jerk reaction, I think it would be worth considering other options before we try to overload them for this. |
There was a specific section on this in the CSSWG wiki but can't find it now cause the wiki is down ): I should note that a sort of an
Yes, there was such issue (couldn't find it) but we agreed that "scroll-driven" is technically and conceptually different from "scroll-trigger". So we closed that one.
Understood, they may be completely orthogonal to this case, just trying to consider sensible defaults. |
Yehonatan and I discussed this IRL while both at CSS Day. Must say I like the general idea of using
Good remark by Brian on not overloading As for bikeshedding: I would name the function FWIW: an alternative idea I had in the back of my mind somewhere was to adjust |
Giving this more thought, using This can be interpreted as 2 possible options:
IMO option 1. is less common, and will only have a meaning for long/infinite animations, and it's probably much more interesting to pursue option 2 with both variations. Naming aside, syntax could possibly looks something like: For 2.a.: .element {
animation-play-state: trigger(in-view 50%, once);
} or for 2.b.: .element {
animation-play-state: trigger(in-view 50%);
} And possibly with .element {
animation-play-state: trigger(in-view 50% / 10% 0);
} Also assuming |
In the early days when we discussed this, we recognized that this was not complicated to enable for animations, but we were concerned about how developers could use this to start transitions as it seemed like a natural thing people would want to do. There was a proposal to have a media query style syntax in #4339. See also #7478. e.g. @scroll-trigger(>500) {
/* style rules to trigger animation or transition */
} The issue with this is that evaluating this change requires a global style recalculation and as such would be unlikely to be able to be started on the compositor. I'm happy to solve this for animations which if we set up up-front we could dynamically trigger from the compositor. We should think about whether there are any ways we could set this up for transitions as well. E.g. maybe for transitions we could do something similar to I don't think it's a good idea to re-use
My thinking around this is that it is somewhat similar to .element {
animation-trigger: trigger(view(), entry 100%) once;
} In general the property might look something like:
The initial value would match the current behavior that animations "trigger" once when they are defined. |
Transitions, unlike animations, can't use the trigger in a property/value since they are triggered by the cascade itself. Having excluded the option for having a trigger as a selector, I think the only option still being discussed now is using state queries for that in #6402. I think that direction may also prove useful for the more advanced use-case for animations, when you want to separate the triggering element from the animated element.
Yes, these 2 options sound option 2 I mentioned above. The main problem I see with introducing a new property and not extending
I'm not sure we need the a point on a timeline. The time-based one is simply a delay, right? And the scroll-based one may be confusing, because what you probably want is a simply intersection, no matter which direction or point on the view-timeline the element is at. E.g: what happens with I guess if we add something like
I really like this part! Kind of binds together all the use-cases (: |
My apologies, I missed that this was the behavior you proposed for it. I still worry this isn't well described by the paused
If you think of this as similar to animation-delay, the animation is just "running" the whole time but it's in the before phase until triggered (i.e. only producing an effect if you have
When given a document timeline yes. I was thinking in the long run you might pass it a point on a (yet to be defined) video timeline or other such time-based triggers which are not simple delays.
There are a few ways that a single point could be interpreted.
We could imply all of these options from the proposed It sounds like you're suggesting though that you might want an upper limit, such as trigger a particular animation anytime you scroll between 500px and 1000px (such that a particular element is intersecting the viewport). I think in order to avoid timing issues you'd probably want to trigger even if the user scrolled past the range without ever entering it just so that you'd be in a consistent state regardless of scroll speed. I'm a bit worried this could get into an arbitrarily complex syntax space for multiple triggers, repeating triggers etc, however maybe a range based trigger always plays forward when you enter the range and plays backwards when you leave it and if you don't want one of the directional trigger points it is conceptually infinite / the start or end of the range. |
Yes, it should hold the fill state until triggered and after finishing, so I guess in that sense it's not really the play-state according to the model, and rather a new thing that toggles phases, as you say.
Yep, that sounds good.
Hmm, yes, +1 on that.
Yeah, sort of, you helped realize what I actually wanted is a range in which the computed value is a boolean, rather than progress. So inside it it's true and false outside. And a single toggle-point can be simply from range start to infinity. And these cover well scroll/view/hover/time/etc.
I think that defines the initial direction.
We may probably want to add multiple triggers, but I'd be happy to solve the single case first (: |
@flackr there is a problem with For example take an element with Either way we get a visual jump. |
I think another way to tackle this is by imagining how this would be implemented today: You'd have 2 IntersectionObservers: one for triggering on entry ( So you end up with 2 ranges:
Then, it could become something along the line of: animation-trigger: view(block 15%) cover / view(block -10%) cover repeat; And the second range is optional of course, and has to be larger than the first range (I think that's possible to validate, right?). |
|
I think this is a separate use case here, where you can trigger-in on entry and trigger-out on exit. The initial use-case was to trigger-in and having an option to run the animation only once. |
@bramus, yes, |
@bramus, @flackr, would appreciate your thoughts on what's suggested so far. Perhaps we can wrap up something that can be presented on the agenda for TPAC? Currently what we have is the following:Syntax:
With It would be nice if we could squeeze in a solution for |
ping @mirisuzanne |
To clarify what I suggested earlier, I think it would be helpful to always have a range (i.e. start and end) for all cases. When the end of the range is not specified it could be some form of infinity / auto value so that most of the time developers would only need to specify a start point. Then, it becomes easier to rationalize all of the behaviors. The "trigger" occurs whenever a rendering update results in going from outside of the range to inside of the range or vice versa, and the behavior depends on the mode:
@ydaniv does having a trigger range not fix the discontinuity issue? |
@flackr I’m a bit confused about the proposed range. When I think of a Scroll-Trigger Animation, I think of a certain line that the elements needs to cross, not a range. Say I want to trigger an animation when scrolling past the 1000px scroll offset, would your range then be About the
|
Yes, of course. If you don't expect navigation to an anchor then you're fine with just the start.
Usually "entrance" animations are usually "from" animations, meaning, they animate to an implicit
It's just like scroll vs. view timelines again (: You can set s specific point on the scroll and that's a valid use-case. But usually you'll set a trigger using IntersectionObserver and wait for an intersection, which can better described by view timeline. And the nice extra is that this also fixes the awkwardness of transforms on the same element, that by ignoring them we can reason about the trigger point without worrying about the initial animation frame. |
I can imagine use-cases where we'd want to completely skip an animation when jumping over the range, for example if we have a long page with multiple scroll-triggered animations, and are landing over some sections via an Even more, I can imagine the cases for the “range” being very short, like half a screen high, meaning that we'd only want to trigger an animation when we're in the range, for example if we have some kind of “screen” where we'd want to play some animation when that screen is completely in the viewport. Scrolling from either top or bottom, we'd want to trigger the animation only when the screen is completely in the viewport. |
This can be achieved with what @flackr said above, without a range end the animation will be triggered above, not skipped though. But with
IIUC this should be covered using |
I think I understand now, you want a point before which you can safely restore the before state without it being visible to the user. E.g. to put it in concrete terms maybe the start trigger is on |
I made a crude polyfill of this at https://flackr.github.io/web-demos/scroll-triggered/scroll-triggered.js . I'm hoping this can be helpful in putting together concrete demos. Demo using it: https://flackr.github.io/web-demos/scroll-triggered/ |
For reference: the spec is currently a work-in-progress[1] but this comment[2] describes the API. [1] w3c/csswg-drafts#10128 [2] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I3b273f4565efddd2fd48d407102f9f1376d816dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207949 Commit-Queue: David Awogbemila <awogbemila@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414034}
For reference: the spec is currently a work-in-progress[1] but this comment[2] describes the API. [1] w3c/csswg-drafts#10128 [2] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I3b273f4565efddd2fd48d407102f9f1376d816dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207949 Commit-Queue: David Awogbemila <awogbemila@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414034}
For reference: the spec is currently a work-in-progress[1] but this comment[2] describes the API. [1] w3c/csswg-drafts#10128 [2] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I3b273f4565efddd2fd48d407102f9f1376d816dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207949 Commit-Queue: David Awogbemila <awogbemila@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414034}
…tonly Automatic update from web-platform-tests Parse animation-trigger shorthand For reference: the spec is currently a work-in-progress[1] but this comment[2] describes the API. [1] w3c/csswg-drafts#10128 [2] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I3b273f4565efddd2fd48d407102f9f1376d816dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207949 Commit-Queue: David Awogbemila <awogbemila@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414034} -- wpt-commits: 52bce37bd96221c1fc5a60da383faef154724895 wpt-pr: 50409
Is it intentional not to allow For example, |
…tonly Automatic update from web-platform-tests Parse animation-trigger shorthand For reference: the spec is currently a work-in-progress[1] but this comment[2] describes the API. [1] w3c/csswg-drafts#10128 [2] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I3b273f4565efddd2fd48d407102f9f1376d816dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207949 Commit-Queue: David Awogbemila <awogbemila@chromium.org> Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414034} -- wpt-commits: 52bce37bd96221c1fc5a60da383faef154724895 wpt-pr: 50409
@cdoublev I think it's an overlook. I probably added the |
One thing I noticed while fiddling with the current grammar is that authors cannot use Perhaps (added some productions for better readability)
|
Yes! I noticed too. I think we also have an issue of But then again, if you have |
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673}
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673}
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673}
…a=testonly Automatic update from web-platform-tests Action scroll-triggered CSS animations This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673} -- wpt-commits: 1f1c2a0b71fe705c5d6ca88a42236e8f80386f2c wpt-pr: 51499
…a=testonly Automatic update from web-platform-tests Action scroll-triggered CSS animations This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673} -- wpt-commits: 1f1c2a0b71fe705c5d6ca88a42236e8f80386f2c wpt-pr: 51499
This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673}
…a=testonly Automatic update from web-platform-tests Action scroll-triggered CSS animations This patch implements detecting the trigger conditions for a scroll-triggered animation[1]. Entering the trigger range plays the animation and exiting the exit range (while not within the trigger range) pauses, resets or reverses the animation. AnimationTrigger keeps track of the animation-play-state of the relevant animation and factors that into how to action the animation. [1] w3c/csswg-drafts#8942 (comment) Bug: 390314945 Change-Id: I86849a606474c516965551a9c8cd87ef363f4959 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6355073 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: David Awogbemila <awogbemila@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435673} -- wpt-commits: 1f1c2a0b71fe705c5d6ca88a42236e8f80386f2c wpt-pr: 51499
Entry animations are pretty common on the web. Currently in order to trigger time-based animations when an element enters the viewport we have to use IntersectionObserver.
The problems with this:
IntersectionObserver
s taketransforms
into account, so that messes up the ability to properly know when an element is in viewport when animating from outside of it using transformsThe idea of using an
in-view
selector was dismissed, so another idea is perhaps to extend theanimation-play-state
property to support a sort of "trigger" values instead of onlyrunning
/paused
, and reuse the newanimation-range
values syntax to toggle between these states, which could look like:A good thing about ranges is that they already ignore transforms for SDA, so the same semantics could apply here and help solve this problem of transforms messing with initial position for triggering on viewport intersection.
While this condition evaluates to
false
the value computes topaused
, and when it'strue
it will change torunning
.Another requirement would be to be able to both toggle every time the computed value changes, and also have it set once. Perhaps this could be inferred from the
animation-fill-mode
, so thatboth
andbackwards
are used for those respectively. Or maybe use specific syntax for distinguishing between the two.cc @bramus @flackr
The text was updated successfully, but these errors were encountered: