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.
Live preview
Under the widget on your page: Powered by A2Z Tools
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
<a href="https://a2z.tools/embed/back-to-top-button">A2Z Tools Back to Top Button</a>
[A2Z Tools Back to Top Button](https://a2z.tools/embed/back-to-top-button)
Back to Top Button by A2Z Tools - https://a2z.tools/embed/back-to-top-button
Related widgets
-
A slim bar or small circle that fills as visitors read your article - measured through the article itself.
-
An automatic table of contents from your headings, with active-section highlight and sticky-header offset.
-
Shows "6 min read" on your post, counted from the page's own text at a researched 238 words per minute.
-
Share buttons for 26 networks - inline, floating, mobile bar or one Share button. No social scripts or cookies.
-
"Updated 3 October 2026" from your page's real modified date - meta tags or JSON-LD - never the load time.
-
A Listen button that reads your article aloud with the browser's built-in voices - no audio files, no account.