-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(#1932): implement smooth scrolling for anchor navigation across site #1965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: gh-pages
Are you sure you want to change the base?
feat(#1932): implement smooth scrolling for anchor navigation across site #1965
Conversation
✅ Deploy Preview for expressjscom-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
js/app.js
Outdated
$(document).on('click', 'a[href^="#"]:not([href="#"]):not([href="#top"])', function(e) { | ||
var href = $(this).attr('href'); | ||
if (smoothScrollToElement(href)) { | ||
e.preventDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please remove this line https://github.com/expressjs/expressjs.com/blob/gh-pages/js/menu.js#L186 ? Since default behavior stopped here.
js/app.js
Outdated
// top link | ||
$('#top').click(function(e){ | ||
$('html, body').animate({scrollTop : 0}, 500); | ||
return false; | ||
}); | ||
|
||
// Smooth scrolling for all anchor links | ||
$(document).on('click', 'a[href^="#"]:not([href="#"]):not([href="#top"])', function(e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$(document).on('click', 'a[href^="#"]:not([href="#"]):not([href="#top"])', function(e) { | |
$("#api-doc").on('click', 'a[href^="#"]:not([href="#"]):not([href="#top"])', function(e) { |
We should minimize the scope of this click event. Currently, $(document).on('click'...) attaches the handler to all anchor links with #
across every page. However, smooth scrolling is only needed on API pages, since the TOC exists only there. Scoping it to #api-doc
avoids unnecessary event handling and prevents inconsistent anchor #
behavior on other pages. Also, checking "#api-doc"
exist on page is required before applying click event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
As i mentioned in the issue, this can be handled through CSS, javascript is not necessary.
I am OK with CSS only solution. But this approach comes with some limitations, like we cannot control scroll behavior and can not add header offsets. But it is fine if headings are not hiding behind the header bar on anchor link click. |
Thanks @bjohansebas for the suggestion about a CSS-only solution!
So I’d propose keeping the JS smooth scroll, scoped only to Let me know if you’d prefer another approach! |
The headings are never hidden by the header bar, or at least I’ve been trying to reproduce it and haven’t been able to.
That doesn’t matter in CSS, since the effect will be applied to all elements anyway. * {
scroll-behavior: smooth;
} |
Hi @bjohansebas and @ShubhamOulkar, I’ve updated the implementation to follow your suggestion of a CSS-only smooth scrolling solution.
Let me know if you’d like any further changes! |
css/style.css
Outdated
h1, h2, h3, h4, h5, h6, | ||
[id] { | ||
scroll-margin-top: 120px; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is actually doing anything, and if it's supposed to have the same effect as in the MDN example https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top, then I'm -1 on this, I don't think we should do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without scroll top margin | with scroll top margin |
---|---|
![]() |
![]() |
We can clearly see that margin spaces added to the header on scroll from the top of the viewport.
This property is used to increase visible area around the target element so that it is accessible to the user.
In our context, why it is important?
I expressed my concerns over the issue of hiding headers behind the top navigation bar in a comment above.
But it is fine if headings are not hiding behind the header bar on anchor link click.
This happens if top navigation is positioned sticky at the top. See image, express.raw()
hide behind sticky top navigation.
It is not required right now, without scroll top margin, header scroll into viewport at top 0px. But I think adding some small margin 60px to the top looks good for me. Also our header is 57px height. Maybe I will go with sticky top navigation bar in #1943.
css/style.css
Outdated
/* handle header offset with scroll-margin */ | ||
h1, h2, h3, h4, h5, h6, | ||
[id] { | ||
scroll-margin-top: 120px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scroll-margin-top: 120px; | |
scroll-margin-top: 60px; |
see comment https://github.com/expressjs/expressjs.com/pull/1965/files#r2206464995
@@ -264,11 +278,6 @@ a { | |||
padding-top: 40px; | |||
} | |||
|
|||
#api-doc *:target, #page-doc *:target { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I support removing this
since we are using scroll top margin only on headers.
} | ||
|
||
/* Respect user motion preferences for access */ | ||
@media (prefers-reduced-motion: reduce) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is Good practice to consider accessibility
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do remove this line https://github.com/expressjs/expressjs.com/blob/gh-pages/js/menu.js#L186. On TOC main section heading click, it should scroll to main sections on the page. Currently, it is disabled. Only subsections get scrolled.
…reventDefault for TOC links
Hi @bjohansebas and @ShubhamOulkar, Thanks so much for the thoughtful reviews! Regarding
I’ll adjust the value to 60px as suggested, since our header height is ~57px. Remove Let me know if there’s anything else you’d like tweaked! |
Description
This PR implements smooth scrolling for in-page navigation across the Express.js website as mentioned in Issue : #1932
This improves the user experience by ensuring that navigation to sections via anchor links transitions smoothly, rather than jumping abruptly.
Closes #1932
Video
smooth-scrolling.mp4