Skip to content

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

@saschanaz

Description

@saschanaz

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions