@@ -1700,7 +1700,7 @@ async function navigate({
17001700 await tick ( ) ;
17011701
17021702 // we reset scroll before dealing with focus, to avoid a flash of unscrolled content
1703- const scroll = popped ? popped . scroll : noscroll ? scroll_state ( ) : null ;
1703+ let scroll = popped ? popped . scroll : noscroll ? scroll_state ( ) : null ;
17041704
17051705 if ( autoscroll ) {
17061706 const deep_linked = url . hash && document . getElementById ( get_id ( url ) ) ;
@@ -1711,6 +1711,15 @@ async function navigate({
17111711 // because it natively supports the `scroll-margin` and `scroll-behavior`
17121712 // CSS properties.
17131713 deep_linked . scrollIntoView ( ) ;
1714+
1715+ // Get target position at this point because with smooth scrolling the scroll position
1716+ // retrieved from current x/y above might be wrong (since we might not have arrived at the destination yet)
1717+ const { top, left } = deep_linked . getBoundingClientRect ( ) ;
1718+
1719+ scroll = {
1720+ x : pageXOffset + left ,
1721+ y : pageYOffset + top
1722+ } ;
17141723 } else {
17151724 scrollTo ( 0 , 0 ) ;
17161725 }
@@ -1724,7 +1733,7 @@ async function navigate({
17241733 document . activeElement !== document . body ;
17251734
17261735 if ( ! keepfocus && ! changed_focus ) {
1727- reset_focus ( url ) ;
1736+ reset_focus ( url , scroll ) ;
17281737 }
17291738
17301739 autoscroll = true ;
@@ -2464,7 +2473,7 @@ function _start_router() {
24642473 // /#top and click on a link that goes to /#top. In those cases just go to
24652474 // the top of the page, and avoid a history change.
24662475 if ( hash === '' || ( hash === 'top' && a . ownerDocument . getElementById ( 'top' ) === null ) ) {
2467- window . scrollTo ( { top : 0 } ) ;
2476+ scrollTo ( { top : 0 } ) ;
24682477 } else {
24692478 const element = a . ownerDocument . getElementById ( decodeURIComponent ( hash ) ) ;
24702479 if ( element ) {
@@ -2923,8 +2932,9 @@ let resetting_focus = false;
29232932
29242933/**
29252934 * @param {URL } url
2935+ * @param {{ x: number, y: number } | null } scroll
29262936 */
2927- function reset_focus ( url ) {
2937+ function reset_focus ( url , scroll = null ) {
29282938 const autofocus = document . querySelector ( '[autofocus]' ) ;
29292939 if ( autofocus ) {
29302940 // @ts -ignore
@@ -2936,7 +2946,7 @@ function reset_focus(url) {
29362946 // starting point to the fragment identifier.
29372947 const id = get_id ( url ) ;
29382948 if ( id && document . getElementById ( id ) ) {
2939- const { x, y } = scroll_state ( ) ;
2949+ const { x, y } = scroll ?? scroll_state ( ) ;
29402950
29412951 // `element.focus()` doesn't work on Safari and Firefox Ubuntu so we need
29422952 // to use this hack with `location.replace()` instead.
0 commit comments