w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.52k stars 672 forks source link

[scroll-animations-1] Triggering scroll-based animations once #7478

Open fantasai opened 2 years ago

fantasai commented 2 years ago

In https://github.com/w3c/csswg-drafts/issues/4354#issuecomment-824929221 @JayGeorge wrote:

Would it be possible only to trigger scroll-based animations once?

This is an option in the scroll-trigger library 'AOS' (or 'Animate on Scroll') – https://github.com/michalsnik/aos#1-initialize-aos – See the 'once' option.

The use case would be: Sometimes, I would like to scroll back up a page and re-read content without having it 'introduced' a second time with animation. For me, this is like a halfway house between some animation but not too much.

Wanted to file this into its own issue for consideration.

ydaniv commented 2 years ago

From what I can see, the library linked above is not for scroll-linked animations, but for scroll/viewport-triggered animations, so probably not relevant at this stage.

flackr commented 2 years ago

We used to have a note in the spec (removed here) that said scroll triggered animations were currently out of scope, it might be worth bringing this back so that it's clear it's currently out of scope. Note this was also previously discussed in #4339. I certainly welcome ideas for how to do this but the mechanism is very different in that it likely will still involve the animation being attached to the document timeline rather than a new timeline.

ydaniv commented 2 years ago

Well, it's simply a whole different family. -linked effects have their timeline attached to a continuous event that sets effect's progress accordingly, while -triggered ones have a usual time-based timeline. So this would normally be achieved today via IntersectionObserver, which currently hasn't a CSS counterpart, but I guess maybe in the future with Toggles via new "viewport" trigger? 🤔

fantasai commented 1 year ago

@flackr There's a short note in the Introduction currently that says

Note: Scroll-driven animations, whose progress is linked to the scroll position, are distinct from scroll-triggered animations, which are triggered by a scroll position, but whose progress is driven by time.

The removed text you link to has a bit more information, do you want to update the note a bit further or do you think it's fine as-is?

bramus commented 1 year ago

Closing this one in favor of #8942. Some good discussion about this going on in there.

bramus commented 1 year ago

Reopening as https://github.com/w3c/csswg-drafts/issues/8942 is more concerned scroll-triggered animations (which could also run just once). Both topics can be resolved on independently.

ydaniv commented 1 year ago

@bramus if this issue was reopened to discuss scroll-driven animations that run once, then isn't it something that can be easily achieved using fill mode that's either none or backwards?

bramus commented 1 year ago

I don’t think they should be tied together. The default value for animation-fill-mode being none also makes this impractical.

ydaniv commented 1 year ago

@bramus but this is what you get now OOTB with none, the animation will play once. After reaching 100% progress it will be GC'd.

bramus commented 1 year ago

But if you currently scroll back up – even if you have animation-fill-mode set to none – the animation restarts again, playing from end to start and still linked to scroll. Think of a view-timeline-based animation that fades in an image during the entry 0 entry 100% range: right now, it will fade out again if you scroll back to top.

The idea for once is to prevent the animation from restarting again once you have passed the entry 100% scroll offset. So from the moment the image was entirely faded in (and a first animationend was reached), the animation of the SDA will become inactive and never come active again. The animation-fill-mode applies as it normally would.

ydaniv commented 1 year ago

Right, they persist, sorry I did a wrong check.

But I do understand what you suggest, so in that case yes, there are sites in the wild that use this behavior. So it makes sense to add it.

flackr commented 1 year ago

yes, there are sites in the wild that use this behavior.

Are there sites that use this that aren't just using scroll triggered animations - for which we would have a different mechanism for this (described in issue #8942)? I've only seen scroll triggered animations which trigger once thus far and would be curious to see real-world examples of one time scroll driven animations. When do they consider the animation to have finished and to not start again? At the point when you scroll past the end point of the animation? I.e. it would still restart if you scroll past the start point, back up and then past it again?

bramus commented 1 year ago

Are there sites that use this that aren't just using scroll triggered animations - for which we would have a different mechanism for this (described in issue https://github.com/w3c/csswg-drafts/issues/8942)?

Preferably, the mechanism to have them run only once would be the same.

Maybe we are looking at it wrongly? Right now we seem to be thinking in terms of “how many triggers” but maybe we should look at it in terms of the animation’s lifetime. I.e. is the (finite) timeline allowed to go back in progress or not? Options could be: allowed (default), not-allowed (thereby creating a “sticky timeline” that only can go up), allowed-until-ended.

When do they consider the animation to have finished and to not start again? At the point when you scroll past the end point of the animation? I.e. it would still restart if you scroll past the start point, back up and then past it again?

For SDA, I’ve prototyped a demo that removes the animation once the animation reached animationend. As long the animationend was not reached, the animation will go back. This reflects the allowed-until-ended that was suggested in the previous paragraph.