Page Scrollbar

A thin thumb drawn over the page in place of the window's scrollbar, so sections of different colours meet without a stripe down the right edge.

Default

This page is running one now. Scroll, or move the pointer to the right edge, and drag the thumb.

It only takes over on a mouse or trackpad. Phones and tablets keep their native scrollbar.

Dark previewReplay previewOpen in new tab

Look at the right edge of the window.

The thumb fades in while you scroll and grows when you point at it.

Usage

Every app mounts one in app.vue. While it is mounted the window's own scrollbar is hidden, from the server render on, so the page never shifts when it hydrates, and a dialog or menu that locks the page has no scrollbar width to make up for. A second instance stays idle.

vue
<!-- app.vue (and error.vue, which replaces it) -->
<NuxtLayout>
  <NuxtPage />
</NuxtLayout>
<PageScrollbar />

Dark surfaces

Sections declare what they are painted with in data-surface, the same attribute Surface Header reads. Over dark and photo the thumb turns white. The nearest declared element under the thumb wins.

vue
<!-- The thumb turns white over these sections -->
<section data-surface="dark" class="bg-black text-white">...</section>
<section data-surface="photo" class="relative">
  <img src="/hero.jpg" alt="" class="absolute inset-0 size-full object-cover" />
</section>

<!-- A light card inside a dark section switches back to the theme's ink -->
<section data-surface="dark" class="bg-black">
  <div data-surface="light" class="bg-background">...</div>
</section>

API Reference

PageScrollbar

Accessibility

Keyboard shortcuts and ARIA behavior.

  • Hidden from assistive technology. Wheel, keyboard and touch scrolling stay native.
  • Steps aside while a dialog, drawer or sheet locks the page.
  • Fades without motion when reduced motion is on.