-
Notifications
You must be signed in to change notification settings - Fork 739
Description
In Mozilla bug 1917071 we came across a case where Gecko is firing transitions as a result of calling commitStyles
.
Specifically, for the following content:
#box {
opacity: 0;
transition: opacity 1s;
}
document.querySelector('button').onclick = () => {
let animation = document
.querySelector('#box')
.animate({ opacity: 1 }, { fill: 'forwards', duration: 1000 });
animation.onfinish = () => {
animation.commitStyles();
animation.cancel();
};
};
After analysis, it looks like the problem is that although commitStyles
is defined as triggering a style flush:
Unlike most other methods defined on this interface, calling this method does trigger a style change event (see § 6.13 Model liveness).
It doesn't define when this takes place. Logically it needs to happen towards the start of the procedure so that the latest styles are applied. The code for Gecko and Blink shows they flush style before updating inline style.
Edit: It looks like the spec does define that pending style changes are applied at the start of the procedure ("If, after applying any pending style changes...").
However, there is no requirement to flush styles at the end of the procedure. Furthermore, my reading of the procedure to update the style attribute doesn't require computing style immediately. As a result, the style attribute may be updated but not yet reflected in the corresponding element's computed style.
If the animation is canceled before style is next computed, the changes to inline style will not be reflected in the before-change style since it only requires updating computed values from declarative animations. As a result, canceling the animation can cause a change to be observed and transitions to be fired.
I'm not exactly sure why the bug doesn't reproduce in Blink. Perhaps it is reflecting the changes to the style attribute as part of producing the before-change style?
I think we need to specify that commitStyles
should somehow cause the computed style to be synchronously updated as a result of updating the style attribute—or somehow indicate that commitStyles
followed by cancelling an animation should not trigger a transition. We may need to refine this wording when we tackle #5394, however.