Skip to content

[css-animations][css-transitions] Isolate animation side-effects? #6398

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

Open
andruud opened this issue Jun 21, 2021 · 15 comments
Open

[css-animations][css-transitions] Isolate animation side-effects? #6398

andruud opened this issue Jun 21, 2021 · 15 comments
Labels
css-transitions-1 Current Work

Comments

@andruud
Copy link
Member

andruud commented Jun 21, 2021

(Using "animations" loosely to refer to any of CSS/Web Animations/Transitions/):

There seems to be an underlying idea in the specifications that effects caused by animations should themselves not trigger new animations. We solve this by making things "not animatable", "animation-tainted", etc. With container queries this problem becomes a bit worse, since the animated size of some element can cause the size of a sibling container (for example) to re-evaluate its container query, hence applying a totally different style to its descendants, including new animation- properties. Probably we need some adjustment to the specs to define what should happen when such animation properties appear (or change) because of "animated re-evaluation" of container queries.

The css-transitions spec describes some alternate-reality-styles (before-change style and after-change style) which is used to determine from/to values. This does give a behavior for container queries, but the before/after-change styles now implicitly become before/after-change layouts. The before-change style is particularly painful, since we would need to do layout in a world where existing animations are updated to the current time, producing different animation effects, potentially causing a change in container query evaluation results, arbitrarily modifying the "previous" style and layout. This sounds pretty complicated to me, and I thought we should explore alternatives. And even if we want to keep css-transitions as is, we probably do need some update for css-animations.

What if we isolate all side-effects that happen because of stuff that's animating, such that it can't trigger new animations:

  • Let the base style be the style as it would be without any animation effects applied (of any kind), inheriting from the base style of the parent.
  • Let the before-change style be the base style as of the previous style change event, inheriting from the before-change style of the parent. (I.e. just remember the previous base style).
  • Let the after-change style be the base style as of the current style change event, inheriting from the after-change style of the parent.
  • CSS transitions are triggered using the before-change style/after-change style. (Taking into account the current effect value for re-targeting purposes. The spec already covers that, though).
  • CSS animations are triggered using the after-change style.
  • Let the animated style be the style as of the current style change event, including all animation effects, but taking the computed values of the animation- and transition- properties from the after-change-style.
  • The animation-/transition- properties are ignored on the animated style, hence if they appear/disappear/update because of container queries re-evaluating, then nothing happens. ("Global animation-tainting"). (EDIT: Take the computed values from after-change style instead, see previous bullet point).

Not sure how web-compatible this is, or if this loses us any crucial aspect of the current specified behavior. On the other hand, the interop situation seems pretty poor in this area, and no browser seems to implement the current before/after change style correctly, so there might be wiggle-room.

At the moment I don't have any other great ideas for how to deal with animations and container queries.

@birtles
Copy link
Contributor

birtles commented Jun 22, 2021

What if we isolate all side-effects that happen because of stuff that's animating, such that it can't trigger new animations:

  • Let the base style be the style as it would be without any animation effects applied (of any kind), inheriting from the base style of the parent.

I've certainly come across a few cases where having an API to get the un-animated style would be very useful so introducing this concept at a spec level might be a useful step in that direction.

  • Let the before-change style be the base style as of the previous style change event, inheriting from the before-change style of the parent. (I.e. just remember the previous base style).

I'm not sure about this. It's been a while since I've touched this code but from memory the following clause from the CSS Transitions spec is quite important:

except with any styles derived from declarative animations such as CSS Transitions, CSS Animations ([CSS3-ANIMATIONS]), and SMIL Animations ([SMIL-ANIMATION], [SVG11]) updated to the current time.

Without that, animations end up triggering transitions.

Not sure how web-compatible this is, or if this loses us any crucial aspect of the current specified behavior. On the other hand, the interop situation seems pretty poor in this area, and no browser seems to implement the current before/after change style correctly, so there might be wiggle-room.

I think Firefox should be correct regarding the before/after change styles part including inheritance--the only area where I'm aware it's wrong is with regards to context-sensitive properties like font-size.

@andruud
Copy link
Member Author

andruud commented Jun 22, 2021

Thanks for having a look @birtles.

I'm not sure about this. It's been a while since I've touched this code but from memory the following clause from the CSS Transitions spec is quite important: [...]

Note that I'm redefining the before-change style to be the before-change base style, and the same for the after-change style. The base style does not include any animation/transition effects of any kind, hence the current time of existing animations is not relevant for the purposes of triggering transitions.

I think Firefox should be correct regarding the before/after change styles part including inheritance--the only area where I'm aware it's wrong is with regards to context-sensitive properties like font-size.

I don't doubt that the fundamentals are correct in Firefox. For example I see that all levels are correctly transitioning at the same time in this example. (Not the case in Chrome).

But more interesting are the parts that would be affected by this change, e.g. "complex" inherited interaction between ongoing animations and transitions, as in this example, where no browser gets it right. With this proposal, there would be no transition on #inner at all, since its before/after-change (base) styles are unaffected by animations on #outer, and therefore the before/after-change styles are equal.

Not sure what the full implications of this change would be, and if any losses would be worth it if we gain container queries.

@birtles
Copy link
Contributor

birtles commented Jun 23, 2021

Note that I'm redefining the before-change style to be the before-change base style, and the same for the after-change style. The base style does not include any animation/transition effects of any kind, hence the current time of existing animations is not relevant for the purposes of triggering transitions.

Oh, ok, that makes sense.

But more interesting are the parts that would be affected by this change, e.g. "complex" inherited interaction between ongoing animations and transitions, as in this example, where no browser gets it right. With this proposal, there would be no transition on #inner at all, since its before/after-change (base) styles are unaffected by animations on #outer, and therefore the before/after-change styles are equal.

I think Firefox's CSS handling here is correct but there is a bug due to running background-color animations on the compositor. If you disable the gfx.omta.background-color pref you will see the correct result.

(Quite a while ago I wrote a few tests covering some of these cases but never finished reworking the CSS transitions WPT tests enough that I could add them there: https://bug1192592.bmoattachments.org/attachment.cgi?id=8843824)

@andruud
Copy link
Member Author

andruud commented Jun 24, 2021

disable the gfx.omta.background-color pref you will see the correct result

Ah, I should have chosen the property to animate more carefully. Yes, that looks correct indeed, nice.

@flackr
Copy link
Contributor

flackr commented Jun 25, 2021

  • CSS transitions are triggered using the before-change style/after-change style. (Taking into account the current effect value for re-targeting purposes. The spec already covers that, though).

The starting of transitions will be sort of how it works today based on step 4 of starting transitions in css-transitions-1. I.e. if the end value (which is equivalent to your suggested before-change style) is the same, no new transition is started.

One notable difference with the proposal is that I think setting a property equal to its current animation value normally would have no effect but with your proposed change would start a transition. We could probably carve out an exception for this given that we need to compute the current value to start from anyways.

To make sure I understand the current effect value, if you interrupt a transition like the following:

e.style.transition = 'all 1s linear';
e.style.left = '100px';
setTimeout(() => {
  // getComputedStyle(e).left == '50px'
  e.style.left = '200px';
}, 500);

We would still compute the current effect value from the replaced transition (e.g. left: 50px)?

The animation-/transition- properties are ignored on the animated style, hence if they appear/disappear/update because of container queries re-evaluating, then nothing happens. ("Global animation-tainting").

Does this mean the entire descendant style which matches the container query would be "animated style" rather than base style? E.g. the following wouldn't start an animation on #b?

<style>
@keyframes grow {
  0% { width: 100px;
  100% { width: 1000px;
}
#a {
  animation: grow 5s;
  contain: size;
}

@container (min-width: 500px){
  #b {
    animation: grow 5s;
  }
}
<div id="a">
  <div id="b">
  </div>
</div>

@andruud
Copy link
Member Author

andruud commented Jun 25, 2021

One notable difference with the proposal is that I think setting a property equal to its current animation value normally would have no effect but with your proposed change would start a transition. We could probably carve out an exception for this given that we need to compute the current value to start from anyways.

Not sure if by "current animation value" you mean only effects from CSS/Web-Animations, only effects from transitions, or effects from all of them.

For transitions happening on the same element, it looks like the transition would be canceled in both the current and proposed behavior.

For CSS/Web animations happening on the same element, I think you're right. And yes I suppose we could check the current value for any animations and special-case on that, if necessary.

For transitions/css/web-animations effects inherited from ancestors, I don't think we can do tricks like that. It would just start/update transitions as if no transitions/animations take place in the document.

We would still compute the current effect value from the replaced transition (e.g. left: 50px)?

Yes.

Does this mean the entire descendant style which matches the container query would be "animated style" rather than base style? E.g. the following wouldn't start an animation on #b?

That's right. Animations/transitions are only interpreted on the before/after (base) styles, so if #a's width is less than 500px in the after-change style, #b does not get the animation property applied in the after-change style either.

I was originally going to also say: #b will still ultimately end up with a value getComputedStyle(b).animationName == 'grow', but this is considered a side-effect of #a's animation effect, and therefore, to satisy animations-do-not-trigger-animations, an animation can't be triggered.

However, it probably makes more sense to specify that the computed values of animation- and transition- properties on the animated style are forced to the corresponding values on the after-change style. That way gCS() matches reality to a greater degree.

@andruud
Copy link
Member Author

andruud commented Jun 28, 2021

animation- and transition- properties on the animated style are forced to the corresponding values on the after-change style

Actually, I think it makes sense to do that for all properties which are "not animatable". Otherwise animations can affect writing-mode etc via @container, and writing-mode is supposed to affect how animations resolve.

@flackr
Copy link
Contributor

flackr commented Aug 6, 2021

It's worth considering the complexity in knowing the style without animations means that we would need to perform two layouts. One layout without animations to know which container queries should apply to the base style, and the second for the container queries which end up applying to the animated style.

@andruud
Copy link
Member Author

andruud commented Aug 6, 2021

When there's no "style change event" (i.e. only animations progressing), we also don't need recalculate the base style/layout, since it didn't change. But yes, otherwise that's true.

However, the currently specified definition of "before-change style" already requires us to do a separate style pass (which we currently ignore in Blink) for each style change event. Then container queries comes along and makes it worse by mixing style and layout, so now we also must potentially also do layout twice, using the old style information but with animation effects updated to current time.

@flackr
Copy link
Contributor

flackr commented Aug 6, 2021

Overall this makes sense. I think this is pretty consistent with how you cannot affect animations on descendants using variables due to the animation-tainted rules, though we should revisit those since I think instead of tainting the variables they should use the after-style values.

I remain somewhat concerned about the potential performance cost of multiple layouts, and how easy it will be to understand when some container query animations do not run because the container query was triggered as a result of animation. The latter is already somewhat of an issue with animation-tainted variables and should be addressable with good tooling.

One notable difference with the proposal is that I think setting a property equal to its current animation value normally would have no effect but with your proposed change would start a transition. We could probably carve out an exception for this given that we need to compute the current value to start from anyways.

Not sure if by "current animation value" you mean only effects from CSS/Web-Animations, only effects from transitions, or effects from all of them.

For transitions happening on the same element, it looks like the transition would be canceled in both the current and proposed behavior.

Ah yes, it seems the starting of transitions is already attempting to do something like the proposal here where we look at the non-animated values. I checked and it looks like the reverse-adjusting duration behavior should also work correctly.

For CSS/Web animations happening on the same element, I think you're right. And yes I suppose we could check the current value for any animations and special-case on that, if necessary.

Normally, transitions would not see style changes on elements with active animations because the animation has a higher composite order than the underlying style. I think we'll just need to have a special case here to not start transitions on an element that is currently animating.

However, it probably makes more sense to specify that the computed values of animation- and transition- properties on the animated style are forced to the corresponding values on the after-change style. That way gCS() matches reality to a greater degree.

I agree, the getComputedStyle of "not animateable" properties should be their after-change style.

@dbaron
Copy link
Member

dbaron commented Aug 20, 2021

@andruud and I were just chatting about this proposal, and I wanted to write a few notes about one issue that we discussed. It seems like one of the undesirable effects of this proposal is what happens when there are animations or transitions triggered by a container query change.

To make this somewhat concrete, suppose we have a component that has container queries that give it substantially different styles at (width < 300px) and (width >= 300px). Then let's consider the 4 cases that result from crossing the following pairs of scenarios (which are intentionally using simple cases of transitions and animations rather than what might perhaps be more realistic ones):

  • transition-outside: The component switches from its large to its small styles as a result of a transition. That is, the component starts off with transition: width 6s linear; width: 500px and then a transition is triggered by setting component.style.width = "200px" (which causes the component to flip from its big styles to its small styles 4 seconds into the transition).

  • animation-outside: The component switches from its large to its small styles as a result of an animation. That is, the component is styled with animation: shrink 6s linear both where the animation is:

@keyframes shrink {
  from { width: 500px }
  to { width: 200px }
}
  • transition-inside: Content inside the component has a transition when the component switches from its large to its small styles. That is, there's an element inside the component that has:
#heading { font-size: 12px; transition: font-size linear 3s; }
@container component (inline-size >= 300px) {
  #heading { font-size: 18px; }
}
  • animation-inside: Content inside the component has an animation that begins when the small styles are first shown. That is, there's content that has:
@container component (inline-size < 300px) {
  #logo { animation: roll-in 3s linear; }
}

With the current proposal above, I think the results are as follows (and I think these results are undesirable):

  • transition-outside + transition-inside: The transition inside the container starts at the same time as the outer transition, rather than starting four seconds later when the container actually switches to displaying its small-state styles.

  • transition-outside + animation-inside: Same as previous case.

  • animation-outside + transition-inside: The transition inside the container never happens at all. Instead, the state jumps suddenly when the container switches into its small state.

  • animation-outside + animation-inside: Whether the animation runs depends on what the base style (which is covered up by the animation) is. If the width in the base style is less than 300px, then the animation runs when the page is loaded; if it's more than 300px then it never runs.

I think the expectation is probably that container-query-dependent animations and transitions inside the container should start when the container query starts to apply to layout and to non-animation styles. It's possible this proposal could be modified to produce that result; part of such a modification would include having a style change event inside of the container when the container query evaluation changes, though other changes would be needed as well.

@andruud
Copy link
Member Author

andruud commented Aug 24, 2021

I've implemented a prototype of container-size-change-is-style-change-event, and so far it appears to be a win-win: it gives much more desirable web-facing behavior, and it's also much easier and less expensive to implement (avoids having to know "two layouts" as @flackr was worried about).

Taking this into account, how about this revised proposal:

  • Let the base style be the style as it would be without any animation effects, inheriting from the base style of the parent.

  • Let the before-change style be the base style as of the previous style change event.

  • Let the after-change style be the base style as of the current style change event.

  • Let the animated style be the style as of the current style change event, including all animation effects, inheriting from the parent's animated style.

    • Note: It should no longer be possible for any "not animatable" property to differ from the the corresponding base style, so no need to specify that we use computed values from the after-change style.
    • Note: Only the animated style is "seen" by layout; there is no "base layout".
  • A container size change acts as a style change event within that container. This means the base style of descendants may be affected by animation effects that influence the container's size.

At first I was worried that this would be a problem for container units, since they act as mini-container queries that dynamically respond to any change in container size. With this proposal, if you define a transition on something that uses container units, and also animate the size of that container, then it would trigger a transition on each frame. However, I think this is expected and non-fatal:

  • Container units already intrinsically respond to the (animated) container size. I don't think authors need to define a transition on top of this.
  • It seems consistent with what would happen today with an animated iframe + inner viewport units. (Well, for what that's worth ...)

So to me the container units situation looks acceptable.

@flackr
Copy link
Contributor

flackr commented Aug 24, 2021

Overall this sounds great! I'm glad that we can behavior that makes sense to developers

How are container units defined? I would have thought that they would be similar to percentages, viewport units or calc where the computed value is a calc that does not itself change when the input variables change. Unfortunately, I can see that this is not the case at least for vw from the demo I put together to test this. It seems there is plenty of precedent for it starting transitions.

@dbaron
Copy link
Member

dbaron commented Aug 24, 2021

I think it sounds good to me as well, except that:

  • Let the base style be the style as it would be without any animation effects, inheriting from the base style of the parent.

probably needs to be specified differently, since I think in the revised proposal it does include some animation effects (those resulting from container queries that change in animations, or maybe all container queries), and something will need to define exactly which animation effects are included and which aren't.

@andruud
Copy link
Member Author

andruud commented Aug 24, 2021

How are container units defined? I would have thought that they would be similar to percentages, viewport units or calc where the computed value is a calc that does not itself change when the input variables change.

The only thing that "survives" to used-value time, is %. Everything else, including viewport units and container units are resolved to px at computed-value time, or sooner.

But yes, specifying that container units are resolved used-value time would probably be the way to "fix" the problem, if we were to define this as a problem.

in the revised proposal it does include some animation effects

Yeah, agree. Should be more specific than "animation effects". Perhaps:

  • Let the base style be the style as it would be without any declarations from the "animation" and "transition" origins, inheriting from the base style of the parent.

And then "animation effects" can still sneak its way into the base, since an animating container can affect the author/user origin of descendants.

blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this issue Sep 9, 2021
This CL implements a new approach [1][2] for dealing with animated
container queries. The approach can be summarized as:

  1) Delaying application of the CSSAnimationUpdate until after
     layout, and
  2) Remembering the "original" old-styles for relevant elements.

Both of these things were also required for the previous solution
(currently behind the runtime flag CSSIsolatedAnimationUpdates),
so they are already mostly in place. Apart from these two things,
however, the new solution actually has more in common with how
things already work on stable than with CSSIsolatedAnimationUpdates,
so this this CL effectively reverts that code.

The new approach in this CL works like this:

 - During StyleResolver::ResolveStyle, elements that have a non-
   empty animation update gets added to a set on DocumentAnimations.
 - A stack-allocated object CSSAnimationUpdateScope is placed on the
   sites where we do style and layout, and it ensures that any
   collected pending updates are applied before we exit that scope.
 - Old-styles are temporarily added for each element we resolve
   style for, with a lifetime that's also tied to
   CSSAnimationUpdateScope.

Regarding InApplyAnimationUpdateScope: it turns out that applying
an animation update can cause calls to Element::
SetNeedsAnimationStyleRecalc. On main, these calls are ignored,
because we always apply the animation update during style recalc,
and we early-out from SetNeedsAnimationStyleRecalc if we're currently
in style recalc. With the changes in this CL, we apply the same
update *after* style recalc, so we need another way to early-out
from SetNeedsAnimationStyleRecalc, and this is what the
InApplyAnimationUpdateScope is for.

Note: It probably makes sense to store the elements-with-pending-
      updates set and the old-styles on the CSSAnimationUpdateScope
      itself, but I'll try that in a separate CL.
Note: We still store old-styles for way too many elements. An
      improvement for that is coming soon.

[1] https://docs.google.com/document/d/1Ef9V-Ra_6I3R9DY0o10fZ7HTriPm9oHYw1xUN0bRcHw
[2] w3c/csswg-drafts#6398 (comment)


Change-Id: I735b9113c12ef57696b82470b2256c639884ef48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3129367
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#919696}
FrankEnderman pushed a commit to FrankEnderman/cursemium that referenced this issue Oct 28, 2021
Currently we set a pending update for any element that has an
active animation running (see CSSAnimationUpdate::IsEmpty), even
if there are no actual *updates* (as in CSSAnimationUpdate::HasUpdates)
to apply. This is because of the unfortunate PreviousActive-
InterpolationsForAnimations map that we need to maintain.

With CSSDelayedAnimationUpdates enabled, setting pending updates is
more expensive than before, since elements with updates enter
a HashSet (CSSAnimationUpdateScope::elements_with_pending_updates_)
that is iterated though later. On some benchmarks, this shows up
as smoothness/frame-time regressions since a large number of
elements are added to the set on every frame.

Ideally we would only set pending updates when there actually *are*
updates, but this is currently[*] not possible because we have to
maintain the aforementioned PreviousActiveInterpolationsForAnimations-
map.

However, we can still take one step in the right direction. Since we
only care about the *keys* in the previous-map, we can avoid updating
it if we know that the keys didn't change. This means that for "stable"
animations that don't constantly change which properties are affected,
we can avoid setting the pending update on each frame.

[*] We may be able to in the future, depending on which details we
    land on here: w3c/csswg-drafts#6398

Bug: 1262215, 1180159
Change-Id: I2a0789b36ee41b123a97b4804311e45a243ae8b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3241146
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#935512}
FrankEnderman pushed a commit to FrankEnderman/cursemium that referenced this issue Oct 29, 2021
In order to advance spec changes for css-transitions that are
necessary for container queries [1], we need to know how often
a transition is blocked from starting because of interference from
an animation on the same property.

[1] w3c/csswg-drafts#6398

Bug: 1180159
Change-Id: I1b59231499e63760a272d2add7cf14d5a1f4c1d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3250820
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#936072}
blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this issue Oct 29, 2021
This reverts commit 83eb3e4.

Reason for revert: Performance and memory regressions, see bugs.

Fixed: 1264284, 1264285

Original change's description:
> Reduce number of pending CSSAnimationUpdates
>
> Currently we set a pending update for any element that has an
> active animation running (see CSSAnimationUpdate::IsEmpty), even
> if there are no actual *updates* (as in CSSAnimationUpdate::HasUpdates)
> to apply. This is because of the unfortunate PreviousActive-
> InterpolationsForAnimations map that we need to maintain.
>
> With CSSDelayedAnimationUpdates enabled, setting pending updates is
> more expensive than before, since elements with updates enter
> a HashSet (CSSAnimationUpdateScope::elements_with_pending_updates_)
> that is iterated though later. On some benchmarks, this shows up
> as smoothness/frame-time regressions since a large number of
> elements are added to the set on every frame.
>
> Ideally we would only set pending updates when there actually *are*
> updates, but this is currently[*] not possible because we have to
> maintain the aforementioned PreviousActiveInterpolationsForAnimations-
> map.
>
> However, we can still take one step in the right direction. Since we
> only care about the *keys* in the previous-map, we can avoid updating
> it if we know that the keys didn't change. This means that for "stable"
> animations that don't constantly change which properties are affected,
> we can avoid setting the pending update on each frame.
>
> [*] We may be able to in the future, depending on which details we
>     land on here: w3c/csswg-drafts#6398
>
> Bug: 1262215, 1180159
> Change-Id: I2a0789b36ee41b123a97b4804311e45a243ae8b8
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3241146
> Reviewed-by: Kevin Ellis <kevers@chromium.org>
> Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#935512}

Bug: 1262215, 1180159
Change-Id: Ifd709a26158f86d23d335bffd3f9f32315c69081
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3251067
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#936377}
@andruud andruud changed the title [css-contain-3][css-animations][css-transitions] Isolate animation side-effects? [css-animations][css-transitions] Isolate animation side-effects? May 20, 2022
@andruud andruud added css-transitions-1 Current Work and removed css-contain-3 labels May 20, 2022
andruud pushed a commit to andruud/csswg-drafts that referenced this issue Nov 1, 2024
 - Introduce "base style", which is the computed style as it would be
   without animations/transitions.
 - Define before/after-change style in terms of that base style
   (at two different points in time).
 - There should be no need for the "completed transition" set anymore,
   since the before/after-change styles on a child are blind to any
   effects from transitions/animations happening on the parent.
 - Maintain the behavior that transitions can not start for properties
   affected by animations. Removing this behavior was considered,
   but was deemed impossible from use-counter data showing that ~5%
   of sites may rely on this behavior.

This change stems from Container Queries, which blurred the line
between the style and layout steps of the frame. The spec currently
defines the before-change style as the style of the previous
style change event, but with any animation effects updated to
current time. This is difficult, because it persisting the before-change
world in some form that is responsive to what the (newly updated)
animations actually do. (For example, we'd need to re-resolve var(),
font-relative units, be able to handle revert/revert-layer, etc.)
With Container Queries, this problem becomes substantially worse,
because now we'd also need to maintain the "before-change layout tree",
which in practice is gone at the time we need it.

w3c#6398
andruud pushed a commit to andruud/csswg-drafts that referenced this issue Nov 1, 2024
 - Introduce "base style", which is the computed style as it would be
   without animations/transitions.
 - Define before/after-change style in terms of that base style
   (at two different points in time).
 - There should be no need for the "completed transition" set anymore,
   since the before/after-change styles on a child are blind to any
   effects from transitions/animations happening on the parent.
 - Maintain the behavior that transitions can not start for properties
   affected by animations. Removing this behavior was considered,
   but was deemed impossible from use-counter data showing that ~5%
   of sites may rely on this behavior.

This change stems from Container Queries, which blurred the line
between the style and layout steps of the frame. The spec currently
defines the before-change style as the style of the previous
style change event, but with any animation effects updated to
current time. This is difficult, because it persisting the before-change
world in some form that is responsive to what the (newly updated)
animations actually do. (For example, we'd need to re-resolve var(),
font-relative units, be able to handle revert/revert-layer, etc.)
With Container Queries, this problem becomes substantially worse,
because now we'd also need to maintain the "before-change layout tree",
which in practice is gone at the time we need it.

w3c#6398
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-transitions-1 Current Work
Projects
None yet
Development

No branches or pull requests

5 participants