Skip to content

Instantly share code, notes, and snippets.

@mujahidi
Last active November 3, 2025 16:10
Show Gist options
  • Select an option

  • Save mujahidi/a888d11921c4da8660ec500de2b98b42 to your computer and use it in GitHub Desktop.

Select an option

Save mujahidi/a888d11921c4da8660ec500de2b98b42 to your computer and use it in GitHub Desktop.
Add sticky sidebar behavior using vanilla javascript to keep the sidebar visible while scrolling, and prevent it from overlapping the footer.
// Make sidebar sticky
const sidebar = document.querySelector('.sidebar-form');
const content = document.getElementById('main');
const footer = document.querySelector('.site-footer');
if (sidebar && content && footer) {
let sidebarTop = null;
function recalcSidebarTop() {
const sidebarRect = sidebar.getBoundingClientRect();
sidebarTop = sidebarRect.top + window.pageYOffset;
}
function handleSidebarSticky() {
if (sidebarTop === null) recalcSidebarTop();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const sidebarHeight = sidebar.offsetHeight;
const footerRect = footer.getBoundingClientRect();
const footerTop = footerRect.top + window.pageYOffset;
const windowHeight = window.innerHeight;
// Always remove sticky state first
sidebar.classList.remove('position-sticky');
sidebar.style.top = '';
// If sidebar is below original position, make sticky
if (scrollTop > sidebarTop) {
// Calculate how much space is available between sidebar and footer
// If the sidebar bottom would touch or overlap the footer, pin it flush to just above the footer (with margin)
const stopPoint = footerTop - sidebarHeight - 20;
if (scrollTop < stopPoint) {
// Normal sticky position
sidebar.classList.add('position-sticky');
sidebar.style.top = '20px';
} else {
// Stick the sidebar just above the footer — even if we've reached the bottom of the page
sidebar.classList.add('position-sticky');
// The sticky top is set so the bottom of the sidebar sits 20px above the footer
const offset = footerTop - scrollTop - sidebarHeight - 20;
sidebar.style.top = `${Math.max(offset, 20)}px`;
}
}
}
// Initial positions
window.addEventListener('load', () => {
recalcSidebarTop();
handleSidebarSticky();
});
window.addEventListener('scroll', handleSidebarSticky);
window.addEventListener('resize', () => {
recalcSidebarTop();
handleSidebarSticky();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment