Table of Contents List Template
An intelligent table of contents that sticks to the page and tracks the reader's progress.
This template is ideal for long articles, documentation pages, or any content that benefits from clear, persistent on-page navigation.

About this Template
This component combines a semantic list with CSS and JavaScript to create a premium user experience. The table of contents list is built inside a nav
element and remains visible on the screen using position: sticky
. As the user scrolls through the article, a lightweight JavaScript "scrollspy" automatically detects which section is in view and highlights the corresponding link in the TOC.
Features
- Automatic Highlighting: Uses the performant
IntersectionObserver
API to track the active section without impacting scroll performance. - Sticky Navigation: The TOC stays fixed in the viewport on larger screens for easy access.
- Accessible by Default: Automatically applies
aria-current="true"
to the active link, communicating the user's location to assistive technologies. - Smooth Scrolling: Uses the CSS
scroll-behavior
property for a smooth transition when a user clicks a link. - Self-Contained Code: All functionality is scoped to the
.toc-template
class and uses no external libraries.
Code Breakdown
The layout consists of a parent container with two children: a nav
for the Table of Contents, and a main
for the article content. The TOC itself is a standard nested ul
. Each heading in the main content that needs to be tracked has an id
attribute that corresponds to the href
of a link in the TOC.
The JavaScript first selects all headings that have an id
. It then creates an IntersectionObserver
, which is a modern browser API for efficiently detecting when elements enter the screen. The observer's callback function fires whenever a heading enters or leaves the viewport. Inside the callback, the script finds the TOC link that corresponds to the visible heading and applies an .active
class and the aria-current="true"
attribute to it, while removing them from the previously active link.
Code
Here's the full code for the template: