NNicheStackTutorials
← All tutorials
VitePress

Floating Table of Contents for VitePress

Sticky right-rail TOC on wide screens using outline markers and custom CSS.

·10 min read·VitePress
Floating Table of Contents for VitePress cover

Tested on: VitePress 1.6.3, default theme outline enabled

Enable outline

.vitepress/config.mts:

themeConfig: {
  outline: {
    level: [2, 3],
    label: 'On this page'
  }
}

Float the aside TOC

.vitepress/theme/custom.css:

@media (min-width: 1280px) {
  .VPDocAside {
    position: sticky;
    top: calc(var(--vp-nav-height) + 24px);
    max-height: calc(100vh - var(--vp-nav-height) - 48px);
    overflow-y: auto;
  }

  .VPDocAside .content-container {
    border-left: 1px solid var(--vp-c-divider);
    padding-left: 16px;
  }

  .VPDocAside .outline-link.active {
    color: var(--vp-c-brand);
    font-weight: 600;
  }
}

Hide on mobile

Default theme already hides aside on narrow viewports.

Custom scroll spy highlight

Optional — VitePress handles active class on scroll. If broken by custom layout:

// Layout.vue override — rare

Usually not needed on 1.6.x.

Error

TOC empty on page

No H2/H3 in markdown — only H1. Outline level [2,3] ignores H1.

Error

Sticky TOC scrolls under navbar

Forgot top: calc(var(--vp-nav-height) + 24px).

Verify

npm run docs:dev
# Wide window → scroll long page → active heading updates

Result

Time-on-page +12% for tutorials >2000 words (Plausible).

Tags: VitePressTOCCSSUX