GitHub

Back to Top

Floating button that appears once the page is scrolled past a threshold and smooth-scrolls back to the top on click.

Stable wc import '@esa/ecology/esa-back-to-top';

Try it

The element is mounted on this page. Scroll down past ~300px and a button appears pinned to the bottom-right corner — click it to smooth-scroll back up.

<esa-back-to-top></esa-back-to-top>

Keep scrolling… the back-to-top button is pinned bottom-right.

API

Attributes and properties:

PropTypeDefaultDescription
threshold number 300 Scroll distance (px) before the button fades in.
smooth-scroll boolean true Smooth vs instant scroll-to-top. (Property: smoothScroll.)
scrollTarget HTMLElement | null null JS-only property — element to track instead of window.
visible boolean (reflected) false Reflected attribute set when scrolled past the threshold; drives the fade/translate.

No custom events — clicking the button scrolls the target (or window) to the top directly.

Accessibility

  • Renders a native <button> with aria-label="Back to top".
  • While hidden it is pointer-events: none with opacity: 0, so it isn't a click target until visible.
  • Visible focus ring via the --focus-ring-* tokens; the chevron icon is aria-hidden.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--back-to-top-bg component #46a758 via --color-primary--color-grass-9
--back-to-top-bottom component 1.5rem via --spacing-500
--back-to-top-radius component 9999px via --radius-full
--back-to-top-right component 1.5rem via --spacing-500
--back-to-top-size component 44px
--back-to-top-text component #fcfcfc via --color-text-inverse--color-gray-1
--focus-ring-color component #65ba74 via --color-border-focus--color-grass-8
--focus-ring-width component 2px
--color-primary-hover semantic #3e9b4f via --color-grass-10
--focus-ring-offset semantic 2px
--transition-base semantic 200ms ease
--transition-fast semantic 150ms ease
--shadow-300 primitive 0 6px 24px -6px rgba(0, 0, 0, 0.07)
--shadow-400 primitive 0 8px 32px -8px rgba(0, 0, 0, 0.08)
--z-sidebar primitive 100