Reputation: 7002
I've noticed some odd behaviors with view transitions and scroll restoration in Chrome and I'm trying to understand if these are bugs or it is intended behavior. I can't find any official information on how they are supposed to behave in combination with scrolling.
I've created a fiddle that emulates an SPA with two pages: one with a small blue ball at the end of the page and one with a large blue ball at the top of the page.
If I
Chrome will
That it first restores the scroll position before starting the animation results in a discontinuity in the animation that IMO completely destroys the point of it.
Am I doing something wrong, e.g. is there something wrong with how I do the SPA functionality, or is this a Chrome bug, or is it intended behavior?
--
This is the code:
let page = 0;
function render() {
let body = '';
if (page == 0) {
for (let i = 0; i < 13; i++) {
body += `<p>.</p>`;
}
body += `<div style="height: 30px; width: 30px; border-radius: 100%; background-color: blue; view-transition-name: bar"></div>`
} else {
body += `<div style="height: 300px; width: 300px; border-radius: 100%; background-color: blue; view-transition-name: bar"></div>`
for (let i = 0; i < 13; i++) {
body += `<p>.</p>`;
}
}
document.querySelector('#content').innerHTML = body;
document.querySelector('a').innerHTML = page == 0 ? 'Next' : 'Back';
}
render();
const useViewTransitions = true;
function transition() {
if (useViewTransitions) {
document.startViewTransition(render);
} else {
render();
}
}
document.querySelector('a').addEventListener("click",
async function(event) {
event.preventDefault();
if (page == 0) {
page++;
history.pushState({
page
}, '');
transition();
} else {
history.back();
}
}
);
window.addEventListener("popstate", ({
state
}) => {
page = state ? .page || 0;
transition()
})
with the following HTML
<div style="height: 30px; width: 30px; border-radius: 100%; background-color: red"></div>
<div id="content">
</div>
<a href="#"></a>
--
I hope the above description was comprehensible. Unfortunately I can't post a video, but this is the instant before I press back on page two (scrolled to the top of the page):
And this is an instant later when it scrolls me down before starting the animation
Upvotes: 2
Views: 1055
Reputation: 11
I ran into a similar problem with a view transition that involved a scroll. My solution was to defer slightly at the beginning and end of the transition function, e.g.
document.startViewTransition(async () => {
await 1;
updateDOM();
window.scrollTo({top: scrollY});
await 1;
})
I think there is a slight race condition between creating the snapshot for the transition and setting the scroll position.
Upvotes: 1