From 9142178b113443749b87c1d259859b42a3d7a9c4 Mon Sep 17 00:00:00 2001 From: Martin Trapp <94928215+martrapp@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:33:49 +0200 Subject: [PATCH] Mt scroll behavior (#8184) * The scrolling behavior of ViewTransition is now more similar to the expected browser behavior * format * removed browser detection --- .changeset/pretty-dancers-admire.md | 5 +++++ .../astro/components/ViewTransitions.astro | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 .changeset/pretty-dancers-admire.md diff --git a/.changeset/pretty-dancers-admire.md b/.changeset/pretty-dancers-admire.md new file mode 100644 index 000000000000..13553488b6b3 --- /dev/null +++ b/.changeset/pretty-dancers-admire.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix: The scrolling behavior of ViewTransitions is now more similar to the expected browser behavior diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index 12dfe0f4f70a..612b89659b8d 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -164,14 +164,21 @@ const { fallback = 'animate' } = Astro.props as Props; } } + // Simulate scroll behavior of Safari and + // Chromium based browsers (Chrome, Edge, Opera, ...) + scrollTo({ left: 0, top: 0, behavior: 'instant' }); + if (state?.scrollY === 0 && location.hash) { const id = decodeURIComponent(location.hash.slice(1)); - state.scrollY = document.getElementById(id)?.offsetTop || 0; - } - if (state?.scrollY != null) { - scrollTo(0, state.scrollY); - // Overwrite erroneous updates by the scroll handler during transition - persistState(state); + const elem = document.getElementById(id); + // prefer scrollIntoView() over scrollTo() because it takes scroll-padding into account + if (elem) { + state.scrollY = elem.offsetTop; + persistState(state); // first guess, later updated by scroll handler + elem.scrollIntoView(); // for Firefox, this should better be {behavior: 'instant'} + } + } else if (state && state.scrollY !== 0) { + scrollTo(0, state.scrollY); // usings default scrollBehavior } triggerEvent('astro:beforeload');