Skip to content
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

[css-transitions] What should happen on transitionend when transition ended but the listener is not called yet? #1820

Closed
saschanaz opened this issue Sep 16, 2017 · 3 comments
Labels
css-transitions-1 Current Work

Comments

@saschanaz
Copy link
Member

Currently Firefox implementation and Chrome/Edge one for transitionend has slight difference.

See this sample:

h2 {
  transition-duration: 4s;
}
/** Resolves when event fires on target element */
function tillEvent(element, eventName) {
  return new Promise(resolve => {
    element.addEventListener(eventName, ev => resolve(ev), { once: true });
  })
}

const track = [
  [400, 200, 0.5],
  [300, 300, 0],
  [200, 400, 0.5],
  [0, 0, 1]
];

button.addEventListener("click", async () => {
  for (const [x, y, opacity] of track) {
    text.style.marginLeft = `${x}px`;
    text.style.marginTop = `${y}px`;
    text.style.opacity = '' + opacity;
    await tillEvent(text, "transitionend");
  }
});

This sample:

  1. applies three properties including marginLeft, marginTop, and opacity,
  2. then waits until the transitionend event occurs,
  3. and then applies next property set (that includes marginLeft, marginTop, opacity).

The intended behavior is that each property set is applied after each transitionend event.

Firefox runs this sample as intended; it applies the properties and waits transitionend on each loop. The element goes 400,200->300,300->200,400->0,0 where each movement takes 4 seconds.

transitionend-firefox

Chrome and Edge does differently: The element goes 400,200->immediately 0,0. I think the event listeners on the second/third loop are immediately fired as the browser still have other two transitionend on their event queue after the first loop.

transitionend-edge

What is the expected behavior here?

@birtles birtles added the css-transitions-1 Current Work label Sep 18, 2017
@birtles
Copy link
Contributor

birtles commented Sep 18, 2017

My guess here is that Edge and Chrome run these event handlers synchronously instead of batching them. CSS Transitions 2 makes it more obvious that they should be batched, but even then it's not entirely clear.

I think we need to tidy up HTML's processing model so that the step that refers to running CSS and dispatching events actual includes sending CSS animation events, CSS transition events, and Web Animations' animation playback events. (See whatwg/html#707). These events should ideally be batched and sorted.

@birtles
Copy link
Contributor

birtles commented Sep 21, 2017

I went through this with @dstockwell from Blink and we think that Chrome and Edge are probably correct here and the Firefox behavior arises due to a bug in Firefox's Promise/microtask handling.

@birtles
Copy link
Contributor

birtles commented Apr 2, 2019

The bug in Firefox's Promise/microtask handling has been fixed since Firefox 60 and the test case now behaves the same in Firefox as in Chrome/Edge.

@birtles birtles closed this as completed Apr 2, 2019
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

2 participants