Scroll Position Issue When Changing Pages #69993
Replies: 4 comments 1 reply
-
@MHBahrampour Thank you for submitting this! This made me realize our documentation needs to be updated.
This is actually expected, and I updated the documentation to reflect it correctly (thank you for flagging this!). We're maintaining scroll position when using
I would argue your tab list should be set to position sticky instead of changing this behavior on Next.js's side. Our code actually bails out correctly when it notices a position sticky.
Can you highlight where this wouldn't be a complete fix? I'm also not seeing this issue on Firefox. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the update! The description now more accurately reflects the behavior. However, what if this isn't the behavior I want? I believe that, regardless of the situation, users should see the entire page (Layout + Page) when visiting a completely new page. Currently, there isn't a proper way to achieve this aside from using hacks or the default HTML tag, which doesn't need much explanation as to why it's not an ideal solution. I'm not an expert, but I honestly don't understand why Link behaves this way. The browser's back and forward buttons are meant for navigating already visited pages, so it's fine to land in the middle of a page. But in Next.js, we usually use Link to navigate to new pages that users are visiting for the first time, so they may miss some content. If it were just me, I wouldn’t question this behavior, but I’ve seen other developers facing the same issue, so it’s safe to say the current behavior isn't sufficient for all situations. That’s why I’m still kindly (and a bit desperately) asking for an option to opt out of this behavior.
Making the tabs sticky isn’t what I want because they would always remain at the top of the page, and I already have a sticky header. Additionally, as shown in the video, when I make the tabs sticky and the window height isn’t enough to fit the entire page, Link scrolls to the top of the page, causing the sticky tabs to overlap part of the page content. making-tabs-sticky.mp4
Not really, let's forget that. |
Beta Was this translation helpful? Give feedback.
-
I disagree with this. The Layout was designed to render only once. Which means, it's really only viable for anything that's truly static (only needs to render once). It's fine if that only your root Metadata, a sticky header, wrapping your Pages with You could probably instead add another dynamic Page (
We have seen this as well. As far as I can see so far, folks have been confused with the scrolling behavior, hence there has been updates to our documentation. I also think there is some confusion around how to properly organize Layouts and Pages.
You can give your Page empty height so it does not overlap. In the meantime, since this is more of a discussion/feature request, I'll be converting this to a discussion. |
Beta Was this translation helpful? Give feedback.
-
The Sidenav from the Next.js Learn tutorial I would consider a "sticky" nav. Many navigation bars on the web (vercel.com, airbnb.com, etc.) are sticky. UX-wise, I don't think it makes sense to have them disappear as you read down. I would then have to scroll all the way back up to navigate somewhere else. The content in your Inner Layout and your expenses, balances, stats Pages are all the same structurally, so you could combine all of them into a dynamic page.
This can also just be in a |
Beta Was this translation helpful? Give feedback.
-
Link to the code that reproduces this issue
https://github.com/MHBahrampour/page-scroll-issue
To Reproduce
Current vs. Expected behavior
Current Behavior
There are two problems with the scroll behavior when navigating between pages:
Note: Layout sections are shown in blue, and Page sections in red.
1. Inconsistent scroll behavior (page has enough height):
inconsistent-scroll.mp4
As shown in the video, when clicking on a group card, sometimes the page scrolls to the top of the group layout, while other times it scrolls to the middle of the new page, cutting off a portion of the layout.
This happens even when the new page (e.g., /groups/rent/expenses) has enough height to display the entire layout and some portion of the page itself. According to Next.js docs for Link component, this is the expected behavior which I think makes it a bug and the new page shouldn't scroll at all in this case.
2. Unwanted scroll to top (page doesn’t have enough height):
scroll-to-top-of-page-issue.mp4
As seen in the video, there are two issues in this scenario:
When clicking a group link (e.g., /groups/rent/expenses), the layout section isn’t visible, which creates a poor user experience.
When clicking on tabs inside the group layout, the tab list itself isn't visible, making it unclear which tab is currently active. If the wrong tab is selected, the user must scroll up to correct it.
Although this issue can be addressed using
scroll={false}
, I wanted to highlight it, as there may be other situations wherescroll={false}
isn't a complete fix. BTW for this one Firefox behaves likescroll={false}
is set.Expected Behavior
Here is what I think is the expected behavior for both problems:
1. Inconsistent scroll behavior:
The scroll behavior should be consistent. The scroll position of the next page should not be influenced by the scroll position of the current page (this is different from preserving the scroll position using
scroll={false}
.2. Unwanted scroll to the top of the page:
While having the option to scroll to the top of the page could be useful in certain cases, it doesn't apply universally. It would be beneficial to have an option to opt-out of this behavior or make it opt-in where necessary.
I've noticed similar open and closed issues on this topic and have tried to be as detailed as possible, so please take this into consideration.
Provide environment information
Operating System: Platform: linux Arch: x64 Version: #1 SMP Fri Mar 29 23:14:13 UTC 2024 Available memory (MB): 7757 Available CPU cores: 16 Binaries: Node: 20.12.2 npm: 10.7.0 Yarn: N/A pnpm: N/A Relevant Packages: next: 14.2.8 // Latest available version is detected (14.2.8). eslint-config-next: 14.2.8 react: 18.3.1 react-dom: 18.3.1 typescript: 5.5.4 Next.js Config: output: N/A
Which area(s) are affected? (Select all that apply)
Navigation
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local), next start (local), Other (Deployed)
Additional context
Project is created using:
Browsers that I tested:
Beta Was this translation helpful? Give feedback.
All reactions