Skip to content
Work in progress - do not use in production. This component is still being built: it is not flagged Ready for Dev, so its markup, attributes, events and styles can all still change without notice, it is not covered by the accessibility gate, and it is not published to npm. It is on this site so the work can be seen and reviewed - nothing more.

ScrollSpy

A list of a page's own sections, built from its headings and following the reading position, rendered as <section is="root-scroll-spy">.

Usage

The spy sits beside the content, not around it: target names the container to read, and the list is built from the headings found in it. An entry carries aria-current while its section is the one being read, and a heading with no id is given one so the entry has something to link to.

Guide

Install

...

Usage

...

Guide

Install

...

Usage

...

<article id="guide">
  <h2>Guide</h2>
  <h2 id="install">Install</h2>
  <p>...</p>
  <h2 id="usage">Usage</h2>
  <p>...</p>
</article>

<section is="root-scroll-spy" target="#guide"></section>

Pages whose sections are mostly one level deeper say so, and get an indented entry per subsection:

<section is="root-scroll-spy" target="#guide" headings="h2, h3"></section>

Which section counts as the one being read

The reading line sits a quarter of the way down the scrollport, and the section being read is the last one whose heading has passed it. Not "the topmost heading on screen": on a short screen three headings are visible at once, and inside a long section none is - and scrolling up, the next heading appears at the bottom of the column long before it is being read, which is one section too far.

What scrolls the content is worked out from the content itself, so a page whose middle column is the scrollport and one that scrolls as a whole document both work with nothing to configure. The spy has to already find that layout when it connects, which on a real page it does - the stylesheets are in <head> and the upgrade happens after them.

Attributes

Attribute Type Default Description
target string (selector) - The container whose headings are listed and spied on; without it the component does nothing
headings string (selector list) h2 Which heading levels to list, e.g. h2, h3
label string the target's h1 What the list is titled

Extends

HTMLElement - use with <section is="root-scroll-spy">. The component dispatches no events: what it has to say is on the list it renders, as aria-current.