Table of Contents
Allows you to quickly navigate the hierarchy of headings for the current page.
import { TableOfContents, tocCrawler } from '@skeletonlabs/skeleton';
Demo
How It Works
Heading IDs
Each page heading requires a unique ID that acts as the scroll target for inner-page navigation.
<h2 class="h2" id="how-it-works">How it Works</h2>
Anchor Links
Each link within the Table of Contents then points to the matching target ID as shown below. Note the use of the #
. When clicked, the browser will automatically scroll so that the targeted element is at the top of the visible screen.
<a href="#how-it-works">How It Works</a>
Custom Title
Customize the table of contents title by editing the default Slot content.
<TableOfContents>
<h1>title here</h1>
</TableOfContents>
Settings
Automatic IDs
Set mode: generate
to enable tocCrawler
to automatically generate and set unique
IDs for all headings that are descendants of the element the action is applied to.
<div use:tocCrawler={{ mode: 'generate' }}>
See the example below. Note this will not overwrite IDs you have set manually.
<!-- Before: -->
<h2 class="h2">Title One</h2>
<h2 class="h2" id="my-custom-id">Title Two</h2>
<!-- After: -->
<h2 class="h2" id="title-one">Title One</h2>
<h2 class="h2" id="my-custom-id">Title Two</h2>
Prefixes and Suffixes
We recommend setting a custom heading (per the instruction above) if a conflict is found within your page. However, you may also hardcode a prefix
or suffix
to all generated IDs as follows:
<div use:tocCrawler={{ mode: 'generate', prefix: 'foo', suffix: 'bar' }}>
<!-- Ex: foo-title-one-bar -->
<!-- Ex: foo-title-two-bar -->
Ignore Headings
To ignore a heading in the target region, append a data-toc-ignore
attribute. The crawler will skip this.
<h2 class="h2" data-toc-ignore>Ignore Me</h2>
Invisible Headings
Use the Tailwind-provided Screen Reader .sr-only
class to append an invisible heading.
<h2 class="sr-only">Include Me!</h2>
Keyed Updates
In some situations you may want to force the crawler action to update on demand. Use the key
parameter and
pass a value that will be modified, which operates similar to Svelte's
key blocks. This can be useful for scanning for
new page headers for tabbed content.
let tabIndex = 0;
// Modifying this value triggers the crawler to run again:
// tabindex = 1;
<div use:tocCrawler={{ key: tabIndex }}>
Active on Scroll
The tocCrawler
action can automatically select the top visible heading when you supply a
scrollTarget
element. That is the element that handles scrolling for the page. By default, this is set to
target the body
element. When using the Skeleton App Shell, designate
scrollTarget: '#page'
element as shown below. To disable this feature, set
scrollTarget: ''
.
NOTE: depending on your page layout, the page may not scroll low enough to activate the final links in the list.
<div use:tocCrawler={{ scrollTarget: '#page' }}>
Dynamic Headings
Generating links constructed using dynamic heading text may result in unexpected behavior.
<h2 class="h2">Greetings {name}</h2>
Svelte will compile and treat this as two seperate DOM elements, only the first of which is included in the generated link.
<!-- DOM -->
<h2 class="h2" id="greetings">
"Greetings "
"skeleton"
</h2>
<!-- Generated Link -->
<a href="#greetings">Greetings</a>
Solution
Use string interpolation to resolve this issue.
<h2 class="h2">{`Greetings ${name}`}</h2>
The component will be compiled as follows.
<!-- DOM -->
<h2 class="h2" id="greetings-skeleton">"Greetings Skeleton"</h2>
<!-- Generated Link -->
<a href="#greetings-skeleton">Greetings Skeleton</a>
Styling
Smooth Scrolling
Use Tailwind's scroll behavior styles to enable smooth scrolling on the scrollable element.
Make considerations for the Reduced Motion settings for proper accessibility.
<!-- If using the App Shell: -->
<AppShell regionPage="scroll-smooth"></AppShell>
<!-- If NOT using the App Shell: -->
<body class="scroll-smooth"></body>
Scroll Margin
Use Tailwind's scroll margin styles if you need to offset for sticky headers
NOTE: not currently supported for Skeleton's App Shell.
<body class="scroll-mt-[100px]"></body>
Sticky Positioning
Use Tailwind's sticky positioning styles to keep the Table of Contents component visible while scrolling.
<TableOfContents class="sticky top-10" />