Skip to content

BackTop ​

A back-to-top button fixed to a corner of the viewport: it auto-appears once you scroll past a threshold, and clicking smooth-scrolls back to the top. Supports custom scroll targets, a scroll progress ring, reverse (scroll-to-bottom) mode, full-width bars and more.

Basic usage ​

By default it auto-detects the nearest scrollable ancestor (falling back to window) and listens to its scroll: the button auto-appears once you scroll past visibility-height (default 400px), and clicking smooth-scrolls back to the top (jumps directly under prefers-reduced-motion).

Basic usage

Custom position ​

Numeric positioning via bottom / right (default 32px).

Custom position

Show / hide control ​

When the visible attribute is present the component is controlled (show/hide fully decided by the host, scroll does not interfere); when absent it auto-toggles by the scroll threshold. Both kinds of switches dispatch oas-visibility-change (detail.visible).

Show / hide control

Show / Hide

State: hidden

Click event ​

Click event

Show button

Custom content ​

The default slot renders custom content (it replaces the built-in arrow icon when present).

Custom content

⬆ Top

Threshold & target container ​

visibility-height tunes the auto-show threshold (default 400); target sets the scroll target container (a CSS selector; when unset it auto-detects the nearest scrollable ancestor, falling back to window): once the container is scrolled past the threshold the button appears, and clicking scrolls back to that container's top.

Threshold & target container

This is a local scroll container: once you scroll past 200px the button at the bottom-right appears; clicking goes back to the container top.

Container bottom — scroll back and try it.

Nested scroll container auto-detection ​

When target is unset the component auto-detects the nearest scrollable ancestor (no selector needed): drop it inside any nested scroll container and it will listen to that container and scroll back to its top. An explicit target always takes priority over auto-detection.

Nested scroll container auto-attach

This is a nested scroll container: the component inside auto-attaches to it (no target set here). Once you scroll past 100px the button at the bottom-right appears; clicking goes back to the container top.

Container bottom — scroll back and try it.

Scroll duration & easing ​

duration controls the scroll duration (ms); easing selects the easing curve (default quart-out).

Scroll duration & easing

Shape & size ​

shape round (default) / square; size three tiers: small (32px) / medium (default, 40px) / large (48px).

Shape & size

Theme variants ​

theme three variants: light (default) / primary / dark (auto-inverted in dark theme to keep contrast).

Theme variants

Transition ​

transition switches the enter/exit transition: fade (default) / scale / none (auto-disabled under prefers-reduced-motion).

Transition

Scroll progress ​

show-progress draws a scroll progress ring around the button edge (computed over the target container scroll range).

Scroll progress

Reverse (scroll to bottom) ​

reverse turns the button into a "scroll to bottom" control: it hides near the container bottom, and clicking scrolls to the container bottom.

Reverse (scroll to bottom)

This is a local scroll container: in `reverse` mode the button appears while you are not at the bottom; clicking scrolls to the bottom.

Container bottom.

Full-width bar ​

expand makes the button span the full viewport bottom (content centered horizontally) and ignores position / bottom / right. This instance appears at the bottom once the page is scrolled past the threshold, and disappears again after clicking back to the top.

Full-width bar

Back to top ↑

Position ​

position is an 8-direction enum (replacing the numeric bottom / right): top-left / top-center / top-right / middle-left / middle-right / bottom-left / bottom-center / bottom-right (middle-* vertically centers).

Position

Tooltip & badge ​

tooltip shows a bubble hint on hover / keyboard focus (linked to the button via aria-describedby for screen readers); badge shows content in a small badge at the button's top-right corner.

Tooltip & badge

Draggable ​

draggable enables drag positioning: press and hold the button and drag to move it freely (movement beyond 4px counts as a drag and does not trigger scroll-to-top; within 4px it counts as a click and still scrolls to the top). The position is persisted to localStorage (key oas-back-top-pos, clearable by the host to reset).

Draggable

Mount point ​

append-to teleports the component under the given container. This instance migrates its host under #bt-app-root (open the devtools to see the DOM move).

Mount point

Mount target container #bt-app-root

API ​

oas-back-top ​

Attributes ​

AttributeDescriptionTypeDefault
append-toTeleport mount point: a CSS selector; on connect the component is moved under that container (kept in place when unset)string—
badgeBadge content: text/number shown in a small badge at the button's top-right cornerstring—
bottomDistance from the viewport bottomstring32px
draggableDrag positioning: press and drag to move the button freely (movement beyond 4px counts as a drag and does not trigger scroll-to-top; within 4px it counts as a click and still scrolls to the top). Position is persisted to localStorage (key oas-back-top-pos, clearable by the host to reset)boolean—
durationSmooth-scroll duration (ms), default 400; 0 or prefers-reduced-motion jumps directlystring400
easingScroll easing function: linear / ease / ease-in / ease-out / ease-in-out / quad-* / cubic-* / quart-* / quint-* / expo-* / circ-* / back-*, default quart-outstringquart-out
expandFull-width bar mode: the button spans the full viewport bottom (content centered horizontally); ignores position / bottom / rightboolean—
position8-direction enum: top-left / top-center / top-right / middle-left / middle-right / bottom-left / bottom-center / bottom-right; replaces the numeric bottom / right positioning when set (middle-* vertically centers); invalid values silently fall back to bottom / rightstring—
reverseReverse mode: becomes a "scroll to bottom" button (hidden near the container bottom; clicking scrolls to the container bottom)boolean—
rightDistance from the viewport right edgestring32px
shapeButton shape: circle (default, round) / square (square corners)stringcircle
show-progressScroll progress ring: a progress ring around the button edge (SVG circle computed over the target container scroll range)boolean—
sizeSize tier: small (32px) / medium (default, 40px) / large (48px)stringmedium
targetScroll target container: a CSS selector; when set the component listens to that container's scroll and scrolls back to its top/bottom; when unset it auto-detects the nearest scrollable ancestor (cached across disconnect/reconnect), falling back to windowstring—
themeTheme variant: light (default, light) / primary (primary fill) / dark (dark surface, auto-inverted in dark theme to keep contrast)stringlight
tooltipHover hint text: shows a bubble tooltip on hover / keyboard focusstring—
transitionEnter/exit transition: fade (default, fade in/out) / scale (zoom) / none; disabled under prefers-reduced-motionstringfade
visibility-heightScroll threshold (px): the button auto-shows once scrolled beyond it, default 400string400
visibleControlled visibility: when present the host fully controls show/hide (scroll does not interfere); when absent the button auto-toggles by the scroll thresholdboolean—

Events ​

EventDescription
oas-clickThe button was clicked (then scrolls to the target container top/bottom)
oas-visibility-changeVisibility state changed, detail: { visible: boolean } (dispatched on both controlled and uncontrolled switches; the initial sync on mount is not dispatched)

Slots ​

NameDescription
defaultCustom button content (replaces the built-in arrow icon when present)

CSS Variables ​

CSS VariableDefault
--oas-back-top-sizevar(--oas-control-height-lg)

The button is fixed to the viewport (the :host is position: fixed, z-index via --oas-z-fixed); when hidden the button gets aria-hidden="true" and the host sets pointer-events: none so it never blocks clicks underneath.

Released under the MIT OR Apache-2.0 License.