Scroll offset - markhowellsmead/helpers GitHub Wiki
Add scroll offset to the page
Adds a scroll offset to the page, to stop anchor disappearing behind a fixed header.
/**
* Adjusts the HTML element offset because of a fixed
* header. The value of --scroll-padding-top should be
* applied to the HTML element element in CSS.
*
* [email protected], this version 7.2.2021
*/
const masthead = document.querySelector('.c-masthead');
document.documentElement.style.setProperty('--scroll-padding-top', 0);
const setAnchorOffset = function () {
const height = Math.floor(masthead.offsetHeight);
document.documentElement.style.setProperty('--scroll-padding-top', `${height}px`);
};
setAnchorOffset();
window.addEventListener('load', setAnchorOffset);
window.addEventListener('resize', setAnchorOffset);
window.addEventListener('orientationchange', setAnchorOffset);
window.addEventListener('scroll', setAnchorOffset);
html {
/* Will be overridden by JS */
--scroll-padding-top: 0;
scroll-padding-top: var(--scroll-padding-top);
}
/* Account for sub-pixel rendering */
[id] {
scroll-snap-margin-top: -0.5px;
scroll-margin-top: -0.5px;
}
Track scroll direction
Add/remove a CSS class on the document root (html
) when scrolling, according to the scroll direction.
/**
* Show masthead on scroll up
* Hide masthead on scroll down to 1/4 of the window height
*/
let lastScrollTop = 0;
window.addEventListener('scroll', function () {
let currentScrollTop = html.scrollTop;
let cutoff = window.innerHeight / 4;
if (currentScrollTop > lastScrollTop) {
// scrolling down
html.classList.remove('is--scrolling-up');
html.classList.add('is--scrolling-down');
if (currentScrollTop > cutoff) {
masthead.classList.add('is--stuck');
}
} else {
// scrolling up
masthead.classList.remove('is--stuck');
if (currentScrollTop === 0) {
html.classList.remove('is--scrolling-up');
html.classList.remove('is--scrolling-down');
} else {
html.classList.remove('is--scrolling-down');
html.classList.add('is--scrolling-up');
}
}
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; // For Mobile or negative scrolling
});