Back to Top Button Widget

Add a back to top button that stays out of sight until a reader is well down the page, then takes them back to the start in one tap. An optional ring around it fills as the page is read, and keyboard users land on your main heading instead of being stranded at the bottom.

Website Essentials Website component No trackers, no cookies Free · no ads

Customize your widget

Placement
0-200. Phones use at most 16.
0-200. Raise it above a chat bubble or cookie bar.
Look
Pill shape only.
Behaviour
CSS selector of the element keyboard focus moves to; none = leave focus on the button.
Light or dark
Match page reads the background behind the component.

Live preview

Exactly what your visitors will see

Embed code

<div data-a2z-kit="back-to-top-button"></div>
<script async src="https://a2z.tools/embed/kit.js" referrerpolicy="no-referrer"></script>

One small script from A2Z draws the component on your page inside its own Shadow DOM. It loads no social-network or tracking scripts and sets no cookies. How the A2Z kit works.

Works with

How it works

The kit draws the button inside a Shadow DOM in a corner of the window, so your theme cannot restyle it by accident. It stays hidden (and out of the Tab order) until the window has been scrolled the distance you choose - 400 px by default - and then fades in. The optional ring is an SVG circle whose dash offset follows how far through the scrollable height the visitor is. Pressing the button scrolls the window to the top: smoothly, or instantly when the visitor's system asks for reduced motion. Focus then moves to the element you name (the first h1 by default), so the next Tab starts from the top of the content rather than from the footer. On phones the button keeps closer to the edge and above the home-indicator area.

Method

  • Shown when window.scrollY >= the show-after distance (400 px by default); hidden with visibility:hidden, which also removes it from the Tab order
  • Ring fill = scrollY / (document height - window height), drawn as stroke-dashoffset = 2 x pi x r x (1 - fill)
  • Press: window.scrollTo({ top: 0, behavior: 'smooth' }), or an instant jump when prefers-reduced-motion: reduce is set
  • Focus after the jump: the element matching your selector (default h1), else the first h1, main or article; tabindex="-1" is added only when that element has no tabindex and cannot take focus on its own
  • Corner offsets 0-200 px, capped at 16 px on screens up to 600 px wide, plus env(safe-area-inset-*)

Worked examples

Default button half-way through a long page

Inputs: No options set; 2,000 px of scrollable height; the visitor has scrolled 500 px

Result: A 48 px gradient circle 24 px from the bottom-right corner, visible because 500 >= 400, with its ring a quarter full

500 / 2000 = 0.25, so the dash offset is 75% of the circumference: 103.7 of 138.2 units for the 22-unit radius.

Store pill on the left

Inputs: shape pill, label Top, position left, style accent, showafter 800

Result: A pill reading 'Top' with an up arrow in the bottom-left corner, in the store's accent colour, appearing after 800 px; its accessible name is 'Back to top'

The visible word is contained in the accessible name, so a speech-control user can say 'click Top'.

A label that is not 'Top'

Inputs: shape pill, label Up

Result: Accessible name: 'Up, back to top'

The name starts with the visible text and still says what the button does.

Limitations

  • Pages that scroll inside an inner container (an app shell with overflow:auto on a div) rather than the window are not supported - the button watches the window.
  • The ring shows progress through the whole page, footer included; the Reading Progress Bar measures the article alone.
  • The ring is drawn for the circle shape only.

Where publishers use it

  • A long recipe page where readers scroll past the method, photos and comments and want the ingredients list again
  • A terms or documentation page dozens of screens long, where a keyboard user needs to get back to the navigation without pressing Shift+Tab fifty times
  • A Shopify collection with endless product rows, using the pill shape with the word 'Top' in the store's accent colour
  • A news site that already has a chat bubble bottom-right, so the button moves to the bottom-left corner

Questions

Where does keyboard focus go after the jump, and why does it matter?

A mouse user simply sees the top of the page, but a keyboard or screen-reader user would still have focus on the button at the bottom, so their next Tab would continue from the footer. The button moves focus to your main heading - the first h1 unless you name another element with a CSS selector such as #content. If that element cannot normally take focus it receives tabindex="-1", the only change made to your markup; set data-focus="none" to turn the behaviour off.

Will it collide with a chat bubble or cookie banner in the same corner?

Pick the bottom-left corner or lift the button with the vertical offset (up to 200 px). On phones the offset is capped at 16 px so the button stays within thumb reach, and the safe-area inset keeps it above the iPhone home indicator.

Does the smooth scroll respect motion sensitivity?

Yes. When the visitor's operating system has reduced motion switched on, the page jumps instantly and the button's fade and ring animation are switched off as well.

Does it work with React, Vue or Next.js routing?

Yes. Render the A2Z div on the pages that should have the button and load kit.js once. When your router removes that div the floating button goes with it, and the next page's div mounts a fresh one.

Cite or recommend this tool

If you reference this tool in an article, course or documentation, these formats are ready to copy. They are optional - nothing is added to your site unless you paste it.

A2Z Tools Back to Top Button
https://a2z.tools/embed/back-to-top-button
  • Reading Progress Bar

    Website Essentials Website component New

    A slim bar or small circle that fills as visitors read your article - measured through the article itself.

    Get code
  • Table of Contents

    Website Essentials Website component New

    An automatic table of contents from your headings, with active-section highlight and sticky-header offset.

    Get code
  • Estimated Reading Time

    Website Essentials Website component New

    Shows "6 min read" on your post, counted from the page's own text at a researched 238 words per minute.

    Get code
  • Social Media Share Buttons

    Social Media Social New

    Share buttons for 26 networks - inline, floating, mobile bar or one Share button. No social scripts or cookies.

    Get code
  • Last Updated Date

    Website Essentials Website component New

    "Updated 3 October 2026" from your page's real modified date - meta tags or JSON-LD - never the load time.

    Get code
  • Listen to Article Button

    Website Essentials Website component New

    A Listen button that reads your article aloud with the browser's built-in voices - no audio files, no account.

    Get code

Preview