Table of Contents (TOC) optional

Hierarchical navigation component that auto-generates from page headings with scroll spy functionality for improved document navigation.

Overview

The TOC component provides sticky sidebar navigation that automatically generates from your page's heading structure. It includes scroll spy to highlight the current section and smooth scrolling to sections when clicked.

Key features:

Basic Example

Create a TOC container and initialize it with JavaScript to auto-generate navigation from your content headings.

← This is a static TOC example showing the component structure.

In real usage, the TOC auto-generates from your page headings using JavaScript.

HTML
<aside class="focus-toc" id="myTOC"></aside>

<script>
  // Auto-generate TOC from page headings
  FocusUI.TOC.init('#myTOC', {
    contentSelector: '.content',
    headingSelector: 'h2, h3',
    title: 'On This Page'
  });
</script>

Variants

Size Variants

Adjust TOC size with .focus-toc-sm or .focus-toc-lg classes.

HTML
<!-- Small -->
<aside class="focus-toc focus-toc-sm" id="smallTOC"></aside>

<!-- Large -->
<aside class="focus-toc focus-toc-lg" id="largeTOC"></aside>

Borderless Variant

Remove border and shadow with .focus-toc-borderless for a minimal look.

HTML
<aside class="focus-toc focus-toc-borderless" id="myTOC"></aside>

Compact Variant

Reduce spacing between items with .focus-toc-compact.

HTML
<aside class="focus-toc focus-toc-compact" id="myTOC"></aside>

Style Variants

Choose from 5 different visual styles for active state indicators.

HTML
<!-- Left border indicator (default) -->
<aside class="focus-toc focus-toc-minimal" id="myTOC"></aside>

<!-- Background pill on active -->
<aside class="focus-toc focus-toc-pill" id="myTOC"></aside>

<!-- Dot indicators -->
<aside class="focus-toc focus-toc-dots" id="myTOC"></aside>

<!-- Vertical progress line -->
<aside class="focus-toc focus-toc-line" id="myTOC"></aside>

<!-- Auto-numbered entries -->
<aside class="focus-toc focus-toc-numbered" id="myTOC"></aside>

Common Patterns

Documentation Pages

Typical usage for documentation with sticky positioning and nested structure.

HTML
<div class="docs-layout">
  <aside class="sidebar">
    <!-- Main navigation -->
  </aside>

  <main class="content">
    <article>
      <h1>Page Title</h1>
      <h2>Section 1</h2>
      <p>Content...</p>
      <h3>Subsection 1.1</h3>
      <p>Content...</p>
      <h2>Section 2</h2>
      <p>Content...</p>
    </article>
  </main>

  <aside class="focus-toc" id="pageTOC"></aside>
</div>

<script>
  FocusUI.TOC.init('#pageTOC', {
    contentSelector: '.content article',
    headingSelector: 'h2, h3',
    title: 'On This Page',
    scrollOffset: 80
  });
</script>

Long Articles

For blog posts or articles with a simple TOC showing only top-level headings.

HTML
<div style="max-width: 800px; margin: 0 auto;">
  <aside class="focus-toc focus-toc-borderless" id="articleTOC"></aside>

  <article>
    <h1>Article Title</h1>
    <h2>Introduction</h2>
    <p>Content...</p>
    <h2>Main Topic</h2>
    <p>Content...</p>
    <h2>Conclusion</h2>
    <p>Content...</p>
  </article>
</div>

<script>
  FocusUI.TOC.init('#articleTOC', {
    contentSelector: 'article',
    headingSelector: 'h2', // Only H2, no nesting
    title: 'Table of Contents'
  });
</script>

Mobile Visibility

By default, TOC is hidden on mobile (<768px). Use .focus-toc-mobile to show it.

HTML
<!-- Hidden on mobile (default) -->
<aside class="focus-toc" id="desktopTOC"></aside>

<!-- Visible on mobile -->
<aside class="focus-toc focus-toc-mobile" id="mobileTOC"></aside>

Heading ID Generation

The TOC component automatically generates IDs for headings that don't have them, using a slug of the heading text.

JavaScript
// Heading without ID
<h2>Getting Started</h2>

// Automatically becomes
<h2 id="getting-started">Getting Started</h2>

// Special characters are removed
<h2>What's New in 2024?</h2>
// Becomes: id="whats-new-in-2024"

JavaScript API

The TOC component requires JavaScript for auto-generation and scroll spy functionality.

Initialize

JavaScript
FocusUI.TOC.init('#myTOC', {
  contentSelector: '.content',
  headingSelector: 'h2, h3',
  title: 'On This Page',
  scrollOffset: 100
})

Update

Regenerate TOC when headings change dynamically.

JavaScript
FocusUI.TOC.update('#myTOC')

Destroy

JavaScript
FocusUI.TOC.destroy('#myTOC')

Methods

Method Description
TOC.init(selector, options) Initialize TOC with auto-generation and scroll spy
TOC.update(selector) Regenerate TOC when headings change dynamically
TOC.destroy(selector) Remove TOC and clean up event listeners

Options

Option Type Default Description
contentSelector string 'body' Container to scan for headings
headingSelector string 'h2, h3' CSS selector for headings to include
title string 'On This Page' TOC heading title (empty string to hide)
scrollOffset number 100 Offset in pixels for scroll spy and smooth scroll
smoothScroll boolean true Enable smooth scrolling to sections on click
activeClass string 'focus-toc-link-active' CSS class for active/current link
includeLevel array [2, 3] Heading levels to include (e.g., [2, 3] for H2 and H3)

Accessibility

The TOC component follows accessibility best practices:

HTML
<aside class="focus-toc" id="myTOC" aria-label="Table of Contents"></aside>

CSS Classes Reference

Complete list of CSS classes used by the TOC component:

Class Description
.focus-toc Main TOC container with sticky positioning
.focus-toc-title TOC heading title (e.g., "On This Page")
.focus-toc-list Top-level list container
.focus-toc-item Individual list item wrapper
.focus-toc-link Anchor link to section
.focus-toc-link-active Active/current section highlight
.focus-toc-nested Nested list for H3 under H2
.focus-toc-sm Small size variant
.focus-toc-lg Large size variant
.focus-toc-borderless Removes border and shadow
.focus-toc-compact Reduces spacing between items
.focus-toc-mobile Forces visibility on mobile screens
.focus-toc-minimal Left border indicator style (default)
.focus-toc-pill Background pill on active item
.focus-toc-dots Dot indicators before each item
.focus-toc-line Vertical progress line with highlighted segment
.focus-toc-numbered Auto-numbered entries (01, 02, 03...)

Browser Support

The TOC component works in all modern browsers that support:

Note: For older browsers, the TOC will still display but without smooth scrolling or sticky positioning. The scroll spy and click navigation will continue to work.

Tips and Best Practices

Tip: Use consistent heading levels in your content. Don't skip from H2 to H4 without an H3 in between, as this affects TOC structure and accessibility.
Performance: If you have many headings (50+), consider limiting the TOC to only H2 headings or using a more specific contentSelector to reduce the number of elements tracked by scroll spy.
Dynamic Content: If your content changes after page load (e.g., dynamically loaded sections), call FocusUI.TOC.update('#myTOC') to regenerate the TOC.