#1111: Declarative Interactions

Visit on Github.

Opened Jun 11, 2025

こんにちは TAG-さん!

I'm requesting a TAG review of Declarative Interactions.

This CSS provides a declarative syntax, via the CSS 'animation-trigger' property, for specifying that an input event targeting a particular element should start an animation on another specified element. The syntax is designed to make it possible for an implementation to opportunistically start the animation independently of the window event loop, thereby eliminating a significant source of input response delay.

Further details:

Demo of the kind of performance problems this feature is meant to eradicate. Try interacting with the form elements in the upper part of the page -- the animations should be smooth. Then check the "inject random jank" checkbox at the bottom and try interacting with the other form controls again; response time will be laggy during periods of main thread jank.

Discussions

Log in to see TAG-private discussions.

Comment by @szager-chromium Jun 23, 2025 (See Github)

@Shrinivassab, I must confess that my framework-fu is very weak, so I can't give you substantial answers about how animation-trigger would combine with Angular, Lit, React, etc.

The spec proposal for animation-trigger does feature a scoping mechanism similar to that used by anchor positioning, which doesn't inherently rely on shadow DOM.

This feature is orthogonal to prefers-reduced-motion and other accessibility settings -- it should not change the rendering of animations.

As for custom gestures: I don't know how those things are implemented, but the proposal is limited to events that use the built-in Event interface and dispatch mechanism. Within that constraint, any event type can be specified, including custom events; but custom events will not get the performance benefits available to standard non-custom events.

Discussed Jun 30, 2025 (See Github)

Skipping.

Discussed Jul 7, 2025 (See Github)

Xiaocheng: Motivation is they want to play animations … very common pattern when you interact with certain parts of the page that they show animations. When you click a button, some element nearby is rotated by a certain angle that indicates the element has been clicked.

… Currently, events and JavaScript have to be added, which isn't great. They are proposing a declarative syntax in CSS to allow triggering such animations completely off the main thread.

… Regarding their direction, I think this is good, like it a lot. Like when offloading work from the main thread. Starting/stopping an animation is a very traditional topic in CSS.

Martin: What's your view on the name? Right now, it has an animation trigger. One element triggers the animation of another element. Name here seems to add another layer of indirection. May be appropriate? You can have multiple elements to trigger the elements, and multiple elements to respond to the same name… many-to-many relationship.

Xiaocheng: Think they are proposing a many-to-one relationship…?

Martin: They are using ID selectors, but they could be class selectors.

Xiaocheng: Not following what you meant by using a selector? Does this change the relationship?

Martin: No, doesn't change the relationship. … (Can name be replaced with selector?)

Xiaocheng: Replacing the name with a selector? Think they follow the design of anchor positioning. Think they want the trigger element to be unique. Selector might match multiple elements.

Martin: But that could happen with the name as well, as it has a selector attached to it. Right now, they have an ID selector, that's probably only one thing. But if it was a class selector, it could match more elements than one.

Lola: But shouldn't that be left to the developer to decide? What's the impact?

Martin: Is the extra layer of indirection adding value in some way? Not sure what the value of adding the indirection is.

Matthew: See what you're asking, Martin. Should ask what the rationale is. Related question: Struggling to find the bit where they allow other triggers than just click. Can't find where this is specified. Explainer doesn't mention it either.

Xiaocheng: This is where I want to raise a concern. Didn't find it at first as well. Assume that the trigger functions should match the event names in UI Events. Don't think every UI event qualifies as a trigger. Think this part is underspecified.

… Related concern is this is adding coupling between CSS and UI events spec. Not sure if that's a good thing. Wondering if there's a way to define the trigger functions to not couple with UI events spec.

Martin: Can we replace this behavior with existing capabilities? For example, when clicking something, it gains focus, that could change the DOM, activate different CSS, and thereby trigger an animation.

Xiaocheng: Can this avoid the main thread?

Martin: Think so! There'a brief hit on the main thread, as for any action. But the event doesn't necessarily have to invoke JS, but the DOM instead.

Xiaocheng: Think they're trying to trigger UI events in the compositor thread without redefining UI events.

Lola: In terms of next steps, I think we cannot close this yet. Sounds like there's concerns around the design of trigger functions. You can write a comment to put that back to them.

Martin: Just trying to help out… They have drafted some specs, but they didn't incude links in the explainer. Needs more clarity. Looks like someone had an idea. Might need more discussions.

Lola: Is this an early review?

Martin: If it isn't, it should be one.

Xiaocheng: Is not marked as an early review.

Lola: Doesn't look like other browser vendors were involved. Wait for what they respond. Don't think we can close this for now.

Discussed Jul 14, 2025 (See Github)

Matthew: we had some queries about htis, Martin is particularly interestsed and I agree: why are they adding an extra layer of indiection here, why are they not using selectors? Xiaocheng hasn't come back to clarify.

We did talk about: 1. Asking that (above), 2. it's very underspecified in terms of the set of functions. We assume they come from UI events, but we wouldn't want to use the whole set. but there are things in there that wouldn't make sense as triggering functions.

Looks like no one has asked the question. We could ping Xiaocheng at the plenary, and then I could draft a comment.

Discussed Jul 21, 2025 (See Github)

Xiaocheng: Discussed this two weeks ago, I was supposed to draft a comment, but didn't do it yet.

… There is a point that Martin raised earlier about the indirection of element names. Could you explain this to me?

https://szager-chromium.github.io/declarative-interactions/#solution-sketch

Matthew: There seems to be a layer of indirection, where you give the animation trigger a name, but we don't understand why. Why not simply selectors? What is the advantage of introducing the name?

… Looked at the spec, and had an idea. Maybe they give them a name, so they can skip the shadow tree, but that doesn't seem necessary. But it comes back to why do we need the name?

Xiaocheng: I think anchor positioning should have the same issue, did we discuss it before?

Matthew: We should check back on that, good point.

… Other concern is that they don't specify where the name for the trigger functions come from, very underspecified.

Xiaocheng: Will check anchor positioning and then draft a comment.

Lola: We will come back to this next week.

Xiaocheng: If we've discussed this before, we could send out the comment this week already.

Comment by @xiaochengh Jul 25, 2025 (See Github)

Hi @szager-chromium, the TAG discussed it and are happy with attempts to offload the main thread. We also have a few questions:

  1. Should this be an early design review?
  2. This proposal introduces yet another name into CSS to find the trigger element, while it can be done via selectors. Have you considered using selectors instead of names?
  3. The animation-trigger-event functions seem rather underspecified. The exact design of the set of supported events can be critical to the success of this feature:
    • The click() in the example suggests that we can use those defined in UI Events as trigger events, so that the main thread can be offloaded. However, not all UI events make sense here (e.g. unload), and some must involve the main thread (e.g. input)
    • This adds a strong dependency between CSS Animations and UI Events specs, which might be a heavy maintenance workload in the future.
Discussed Jul 28, 2025 (See Github)

Matthew: Animation triggers, with layers of indirection, where's that at?

Xiaocheng: Proponents already answered questions.

Comment by @szager-chromium Jul 30, 2025 (See Github)

Discussion of the exact CSS syntax is ongoing at:

https://github.com/w3c/csswg-drafts/issues/12336

Comment by @matatk Aug 8, 2025 (See Github)

Hi @szager-chromium; thanks for your updates and answers to our questions. We discussed Declarative Interactions again this week, and I think we will be discussing the proposal again soon.

Regarding the naming/indirection (question 2): Acknowledged that the convention adopted is idiomatic for CSS. That being said, it would be helpful for me and other reviewers if you could clarify the specific reason(s) that you were warned against using the selectors approach. Please could you add that info to the explainer?

The reason for asking is that having the knowledge of other approaches that were tried—and why they were discounted—is really helpful for readers and reviewers of a proposal to understand the trade-offs made during its design. This is especially the case if the reader isn't an expert in the domain of a given proposal.

Thanks again for your updates so far, and in advance for any clarification on question 2 that you may be able to add.

Comment by @tabatkins Aug 8, 2025 (See Github)

Regarding the naming/indirection (question 2): Acknowledged that the convention adopted is idiomatic for CSS. That being said, it would be helpful for me and other reviewers if you could clarify the specific reason(s) that you were warned against using the selectors approach. Please could you add that info to the explainer?

I think I was the one that warned them off - the reason is indeed just that we have an established idiom in CSS for linking two elements, and it's "have one establish a name, and the other refer to that name".

We (the CSSWG) do have reasons for why that particular pattern is generally better than using a selector in a value, but I don't think the reasoning particularly needs to be repeated in every feature that wants to link two elements together. "It's the well-established CSS idiom for referring to one element from another element" should be a sufficient reason here, I think.

(The CSSWG could write up this reasoning in its wiki, if that would be helpful for you and the rest of the TAG in future reviews; I just don't think it's needed for any individual feature review to justify this decision on its own.)

Comment by @matatk Aug 11, 2025 (See Github)

Thanks for the clarification @tabatkins, and for filing the issue, @bkardell.

Speaking as me, I agree it's a good idea to follow the DRY principle in this case - and at the same time, I would also appreciate a centralised rationale on it.

I'll take the 'pending external feedback' label off of this specific issue, so as to unblock it from our end, and expect we will have any further comments in general soon.

Comment by @nt1m Aug 12, 2025 (See Github)

@szager-chromium My two cents would be to add animation-trigger-scope (similar to anchor-scope) in addition to the tree-scoped names. I imagine component based systems will not necessarily want to use IDs.

Comment by @szager-chromium Aug 12, 2025 (See Github)

@nt1m -- adding a scoping property along the lines of animation-trigger-scope is indeed part of the plan and the spec proposal.