Docs sidebar with scroll-spy
A sticky table of contents that highlights the section currently in view, driven by IntersectionObserver.
Tailwind CSSNavigationdocssidebarscroll-spytoc
Live preview
Code
How it works
What it solves
Long documentation pages need a map that tells readers where they are. Listening to scroll events and measuring offsets is wasteful and jittery; this version lets the browser tell you which heading crossed a line.
How it works
The sidebar is a sticky nav with a list of in-page links whose href values match section ids. The script builds an IntersectionObserver with a negative top and bottom rootMargin, which shrinks the observed viewport to a thin band near the top. When a heading enters that band, its link receives the active classes (a left border and stronger text) and the previous one loses them. Clicking a link uses native anchor navigation, and scroll-mt-24 on each section keeps the heading clear of a fixed header. The sidebar is hidden below lg where a top-of-page contents list would be better.
Adapting it
Change rootMargin to move the activation line. Generate the link list from your headings if content is dynamic. For nested headings, add a second list level and mark the parent when any child is active.
Pitfalls
- If two headings sit inside the band at once, the last one wins; keep sections taller than the band.
- Active classes must be toggled, not replaced, or hover styles vanish.
- Add
scroll-behavior: smoothonly with a reduced-motion guard.
How to use it
- Put
docs-sidebar.htmlbeside your article and give each section anidmatching a link. - Add
scroll-mt-24to every section heading. - Load
scroll-spy.jswithdefer. - Change
rootMarginif your header height differs.
Licence: DEV3 Snippet Licence. Free to use, change and ship in personal and commercial projects. Attribution is appreciated, not required. Please do not redistribute snippets as a collection.