Re: [csswg-drafts] [css-animations-2] Move scroll and event animation triggers to independent namespace (#12336)

@ydaniv there's one main thing I don't understand here, which may be one source of confusion?

> But using timelines is not the goal, it's just means to an end. If it complicates the design to make it stateless and fit in with event-based triggers, then it's possible we can simplify this and remove timelines altogether.

Timelines are not stateful. At a given scroll position they produce a single time value. Triggers (and intersection observer) are the things that are inherently stateful. When the timeline or position changes from one value to another they cause events. Events are also not inherently stateful though change events could be argued to be stateful.

The reason that I think event triggers and whatever we define for view or intersection triggering need to be different is that view triggers require a stateful memory of what their last position was and when to update that memory. Additionally, when adding a new animation even if there was no discrete `change` event we still want to put that animation in the correct state for where you are right now.

Also, as @szager-chromium mentioned, other events while they might sound like they are always paired are not. So it would be a mistake to for example say

```css
#source {
  event-trigger: --start pointerdown(), --stop pointerup();
}

/* Attempting to make a button pressed animation may result in the button staying pressed */
#target {
  animation-trigger: toggle --start / --stop;
}
```

From your example https://github.com/w3c/csswg-drafts/issues/12336#issuecomment-3191262699
```css
#source {
  event-trigger: --source-play viewenter(0.2), --source-flip viewleave(0.8);
}

#target {
  animation-trigger: alternate --source-play / --source-flip;
}
```
One thing I'm not sure I understand is how we ensure that an animation plays if you're already in view to start with, or what happens if your ranges overlap, e.g. `event-trigger: --source-play viewenter(0.8), --source-flip viewleave(0.2);`.

> So naturally, we chose to build on top of ViewTimeline to achieve this, and why the design shifted towards using a timeline.

This is an oversimplification, though admittedly the explanation probably got lost somewhere. Part of the reasoning is that as we have more timeline types there are many cases where passing points on a timeline could be valuable to result in triggers. E.g. you could use animation triggers to coordinate starting, reversing, or doing other effects based on the document timeline, or based on new timelines we come up with. Similarly with view timelines we already have an understanding of how you specify ranges.

TLDR, while there's some value to associating with timelines (extends to future defined timelines), the whole concept requires additional details that plain events do not around what causes them to happen, and has additional properties to control when that internal state changes, which generates the corresponding event pairs.

E.g. we could define `view-trigger-*`, omit the timeline part or referring to a view timeline and the source element could be the element it's defined on. However, we'd still need to copy something like the range stuff from view timelines.

-- 
GitHub Notification of comment by flackr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12336#issuecomment-3192262737 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 15 August 2025 17:31:08 UTC