Created
November 17, 2025 19:48
-
-
Save mujahidi/1683621f5772b80ba74cb0eb281692ae to your computer and use it in GitHub Desktop.
Make sidebar sticky using JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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