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'; Angular usage

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.) Property: `smoothScroll`. On by default. Write `="false"` to turn it off — unusually for a boolean attribute, this one reads the value.
scrollTarget HTMLElement | null null JS-only property — element to track instead of window. Set as a JS property — there is no attribute.
visible boolean 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, split by blast radius: the hooks that belong to this component, then the shared and system tokens it consumes alongside everything else. 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.

Wired to this component

No other component reads these — re-point them and esa-back-to-top is the only thing that moves.

Token Tier Resolves to
--back-to-top-size component 44px

Shared tokens it reads

Owned by a family or by the semantic layer. Still overridable — but scope the override (esa-foo { --form-border-color: … }) unless you mean to move everything that reads it. Reach says what else that is.

Token Reach Resolves to
--focus-ring-color component focus ring group · +34 more #3e9b4f via --color-border-default-focus → --color-grass-10
--focus-ring-offset component focus ring group · +31 more 2px
--focus-ring-width component focus ring group · +35 more 2px via --border-width-focus → --border-width-200
--color-background-brand semantic every component #46a758 via --color-grass-9
--color-background-brand-hover semantic every component #3e9b4f via --color-grass-10
--color-content-default-knockout semantic every component #fcfcfc via --color-gray-1
--elevation-3 semantic every component 0 via --shadow-offset-x
--elevation-4 semantic every component 0 via --shadow-offset-x
--radius-pill semantic every component 9999px via --radius-full
--transition-base semantic every component 200ms via --duration-200
--transition-fast semantic every component 150ms via --duration-150
--z-sidebar semantic every component 100
--spacing-500 primitive every component 1.5rem