I am struggling to get the View Transitions API to behave as intended. My guess is that I'm missing something simple. This is a very basic implementation within a single page.
I am showing three blocks on-screen, and swapping the middle block in and out from <template>
content. My expectation is that the content I am swapping with the name view-transition-name
"block-trans" will have the transition
animation applied, and that the other blocks will move smoothly out of the way. In reality, all elements fade out and back in with the default transition.
Abbreviated code below. Example CodePen here.
My assumption was that this would be similar to this example, which, of course, does work.
HTML:
<template id="view1">
<div class="block block-trans" view-transition-name="block-trans">
View 1
<button onclick="swap('template#view2', '.block-trans')">Go to View 2</button>
</div>
</template>
<template id="view2">
<div class="block block-trans" view-transition-name="block-trans">
View 2
<button onclick="swap('template#view1', '.block-trans')">Go to View 1</button>
</div>
</template>
<div class="content">
<div class="block block1" view-transition-name="e1">Test block</div>
<div class="block block-trans" view-transition-name="block-trans">
View 1
<button onclick="swap('template#view2', '.block-trans')">Go to View 2</button>
</div>
<div class="block block1" view-transition-name="e1">Test block</div>
</div>
JS:
function swap(inTemplSelector, outSelector) {
let inTempl = document.querySelector(inTemplSelector);
let inEl = inTempl.content.cloneNode(true).firstElementChild;
let outEl = document.querySelector(outSelector);
if (document.startViewTransition) {
document.startViewTransition(() => {
outEl.replaceWith(inEl);
});
}
else outEl.replaceWith(inEl);
}
CSS:
::view-transition-old(block-trans),
::view-transition-new(block-trans) {
animation: .3s transition 0s ease;
}
@keyframes transition{
from {
opacity: 1;
translate: 0;
rotate: 0;
}
to {
opacity: 0;
translate: 1rem -5rem;
rotate: 8deg;
}
}
I was ignoring that examples were setting view-transition-name
as an inline style rather than an HTML element attribute.
Setting view-transition-name
in your CSS will fix the issue, and providing a unique view-transition-name
for each element (except the one you're swapping) will ensure that the surrounding elements are properly FLIP'd. See working example here.