Skip to content

Instantly share code, notes, and snippets.

@mujahidi
Created November 17, 2025 19:48
Show Gist options
  • Select an option

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

Select an option

Save mujahidi/1683621f5772b80ba74cb0eb281692ae to your computer and use it in GitHub Desktop.
Make sidebar sticky using JS
const sidebar = document.querySelector('.sidebar-is-sticky');
const content = document.getElementById('main');
const footer = document.querySelector('.site-footer');
if (sidebar && content && footer) {
let sidebarTop = null;
let ticking = false;
// Only recalc sidebarTop on load/resize, not on every scroll (prevents flicker)
function recalcSidebarTop() {
const sidebarRect = sidebar.getBoundingClientRect();
sidebarTop = sidebarRect.top + window.pageYOffset;
}
function handleSidebarSticky() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const sidebarHeight = sidebar.offsetHeight;
const footerRect = footer.getBoundingClientRect();
const footerTop = footerRect.top + window.pageYOffset;
// Remove sticky state initially
sidebar.classList.remove('position-sticky');
sidebar.style.top = '';
if (sidebarTop === null) {
recalcSidebarTop();
}
// If sidebar is below original position, make sticky
if (scrollTop > sidebarTop) {
const stopPoint = footerTop - sidebarHeight - 20;
if (scrollTop < stopPoint) {
sidebar.classList.add('position-sticky');
sidebar.style.top = '20px';
} else {
sidebar.classList.add('position-sticky');
const offset = footerTop - scrollTop - sidebarHeight - 20;
sidebar.style.top = `${Math.max(offset, 20)}px`;
}
}
}
// Use rAF to avoid scroll flicker
function rafHandleSidebarSticky() {
if (!ticking) {
window.requestAnimationFrame(() => {
handleSidebarSticky();
ticking = false;
});
ticking = true;
}
}
// On load: recalculate top, then stick if needed
window.addEventListener('load', () => {
recalcSidebarTop();
handleSidebarSticky();
});
// Use rAF on scroll
window.addEventListener('scroll', rafHandleSidebarSticky);
// On resize: recalc sticky baseline and apply stick logic
window.addEventListener('resize', () => {
recalcSidebarTop();
handleSidebarSticky();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment