For AI agents: the complete documentation index is available at https://a3s-lab.github.io/UI/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/UI/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/UI/en/components/back-to-bottom.md.

Back to Bottom

Back to Bottom appears only in an append-only scroll region, letting people return to the live edge without losing the number of updates that arrived while they read earlier content.

Live preview

3 unread updates waiting

You are reading earlier run output

Three updates arrived at the end. New content will not force your reading position to move.

Usage

Place the button inside the element that truly owns scrolling. The controller appears when the distance from the live edge exceeds the threshold or unread updates exist. Reserve data-always-visible for demonstrations and diagnostics.

<div class="transcript-viewport" data-scroll-owner>
  <ol aria-label="Run output">
    <li>Dependency checks completed.</li>
    <li>Documentation build started.</li>
  </ol>
  <button type="button" class="back-to-bottom" data-unread="3">
    <span data-back-to-bottom-label>Return to latest output</span>
    <span data-unread-count>3</span>
  </button>
</div>

For on-demand loading, import the shared runtime before the controller.

import "@a3s-lab/ui/runtime";
import "@a3s-lab/ui/back-to-bottom";

const button = document.querySelector(".back-to-bottom");

button.addEventListener("a3s:back-to-bottom-activate", () => {
  markVisibleUpdatesAsRead();
});

button.setUnread(3);

Parameters

APIDefaultPurpose
data-scroll-targetNearest [data-scroll-owner]CSS selector for another scroll owner
data-threshold96Distance from the end, in pixels, before the button appears
data-unread0Current unread update count
data-always-visibleOmittedForces visibility for demonstration or diagnosis only
data-back-to-bottom-labelRequiredLocalized visible action name
data-unread-countOptionalUnread count; values above 99 display as 99+

JavaScript API

Method or eventPurpose
getState()Returns { atBottom, unread, visible }
setUnread(count)Updates the unread count and visibility
scrollToBottom(options)Scrolls to the live edge and clears unread by default
refresh()Reconnects after the DOM or scroll owner changes
a3s:back-to-bottom-activatePublishes the user's or API's return-to-bottom intent
a3s:back-to-bottom-visibility-changePublishes a visibility change

States and variants

hidden means the reader remains at the live edge with no unread updates. visible means the reader moved away from the end. unread means new content is waiting. New content increments the count without scrolling. A deliberate return clears the count and respects prefers-reduced-motion.

Use this action only for an independently scrolling, append-only region such as run output, a conversation transcript, or an event stream. Short lists, static articles, and page-level scrolling do not need it.

Accessibility

Use a native button with a clear action name. Keep the unread count visible and explain its meaning through the button name or accessible text on data-unread-count; an isolated number is not enough. New content must not steal focus or force scrolling. If the product has another live-announcement region, do not announce each update again through this control. The button controls only its owning scroll region and leaves the tab order when hidden. The host owns transport, read receipts, virtualization, and business counts; the component owns scroll position, visibility, and return intent.