Skip to content
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

Add smooth scroll behavior #2819

Draft
wants to merge 3 commits into
base: staging
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion site/gatsby-site/gatsby-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,51 @@ export const shouldUpdateScroll = ({ routerProps: { location } }) => {
}
};

const onRouteUpdate = ({ location }) => scrollToAnchor(location);

/**
* Scrolls smoothly to the anchor specified in the URL hash.
* If the page is still loading, it waits until the document is fully loaded.
* It uses requestAnimationFrame for efficient checking and scrolling.
*
* @param {object} location - The location object containing the URL.
* @param {number} mainNavHeight - The height of the main navigation to offset the scroll position (default is 0).
*/
function scrollToAnchor(location, mainNavHeight = 0) {
if (location && location.hash) {
const checkAndScroll = () => {
if (document.readyState === 'complete') {
const item = document.querySelector(location.hash);

if (item) {
const itemTop = item.offsetTop - mainNavHeight;

const itemBottom = itemTop + item.offsetHeight;

const viewportTop = window.scrollY;

const viewportBottom = viewportTop + window.innerHeight;

// Check if the item is already in view
if (itemBottom > viewportTop && itemTop < viewportBottom) {
return;
}

window.scrollTo({
top: itemTop,
behavior: 'smooth',
});
}
} else {
requestAnimationFrame(checkAndScroll);
}
};

requestAnimationFrame(checkAndScroll);
}
return true;
}

import { wrapRootElement, wrapPageElement } from './gatsby-shared';

export { wrapPageElement, wrapRootElement };
export { wrapPageElement, wrapRootElement, onRouteUpdate };
1 change: 1 addition & 0 deletions site/gatsby-site/src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ html {
body {
font-family: 'Karla', sans-serif !important;
font-size: 16px;
scroll-behavior: smooth;
}

html, body, #___gatsby, #gatsby-focus-wrapper {
Expand Down
Loading