diff --git a/.changeset/tiny-poems-scream.md b/.changeset/tiny-poems-scream.md new file mode 100644 index 000000000000..813972867a0e --- /dev/null +++ b/.changeset/tiny-poems-scream.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: use `fill: 'forwards'` on transition animations to prevent flicker diff --git a/packages/svelte/src/internal/client/dom/elements/transitions.js b/packages/svelte/src/internal/client/dom/elements/transitions.js index cc895cbccbcc..38100e982cce 100644 --- a/packages/svelte/src/internal/client/dom/elements/transitions.js +++ b/packages/svelte/src/internal/client/dom/elements/transitions.js @@ -381,9 +381,15 @@ function animate(element, options, counterpart, t2, on_finish) { // create a dummy animation that lasts as long as the delay (but with whatever devtools // multiplier is in effect). in the common case that it is `0`, we keep it anyway so that // the CSS keyframes aren't created until the DOM is updated - var animation = element.animate(keyframes, { duration: delay }); + // + // fill forwards to prevent the element from rendering without styles applied + // see https://github.com/sveltejs/svelte/issues/14732 + var animation = element.animate(keyframes, { duration: delay, fill: 'forwards' }); animation.onfinish = () => { + // remove dummy animation from the stack to prevent conflict with main animation + animation.cancel(); + // for bidirectional transitions, we start from the current position, // rather than doing a full intro/outro var t1 = counterpart?.t() ?? 1 - t2;