Skip to content

BackToTop

A portal-rendered floating button that reveals after the user scrolls past a threshold and returns to the top of the page when clicked.

  • stable
  • since v0.1.0
  • 1.1 kB
  • navigation
  • scroll
  • accessible

Renders an IconButton with an accessible label; toggles a data attribute for visibility rather than removing from the tree.

Preview
Open
tsx
import { BackToTop } from "@arshad-shah/cynosure-react";
<BackToTop showAfter={300} position="bottom-right" />

The button is rendered through a Portal so it floats above the rest of the page; pass disablePortal to render it inline (useful in tests).

showAfter controls how many pixels the page must scroll before the button appears. The default is 300.

Preview
Open
tsx

Use position to anchor the button to one of three corners along the bottom edge.

Preview
Open
tsx

Replace the default chevron with any ReactNode via the icon prop.

Preview
Open
tsx

Pass disablePortal to render the button at its current position in the tree.

Preview
Open
tsx
PropTypeDefaultDescription
showAfter
number
300
Scroll distance (in px) past which the button becomes visible.
position
"bottom-right"|"bottom-left"|"bottom-center"
bottom-right
One of the corner / center positioning presets.
smooth
boolean
true
Use smooth scrolling on click. Forced to `"auto"` under `prefers-reduced-motion: reduce`.
container
Element|DocumentFragment|(() => Element|null)
Portal target. Defaults to `document.body`.
disablePortal
boolean
Render inline (skip portal). Useful in tests or when the parent scroll container isn't `document`.
icon
ReactNode
Replace the default chevron-up icon.
label
string
Back to top
Accessible label for the icon-only button.
  • The underlying element is a <button> rendered via Cynosure’s IconButton; the icon is hidden from assistive tech.
  • label (default "Back to top") becomes the button’s accessible name — override for localisation.
  • A data-visible attribute reflects the visible state so consumers can style the show/hide transition without re-mounting.
  • When prefers-reduced-motion: reduce is set, smooth is ignored and the page jumps instantly.
  • The button remains tab-focusable while hidden, but data-visible="false" lets CSS hide it from sight.
  • Mount once at the root of your layout — it positions itself fixed via the position preset.
  • Lower showAfter (e.g. 120) on shorter pages so the affordance appears sooner.
  • Set disablePortal inside unit tests where document.body doesn’t exist yet.
  • Use container to portal into a scroll container other than document.body for scoped layouts.