webdevpuneet.com

Back to Top Button — Free HTML CSS JS Scroll-to-Top Snippet

Back to Top Button · Scroll · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="page" id="page">
  <div class="hero">
    <h1>Scroll down to see the button appear</h1>
    <p>Keep scrolling — a floating button will fade in once you pass the threshold, and smooth-scroll you back to the top on click.</p>
  </div>
  <section class="block" id="s1"><h2>Section One</h2><p>Long pages benefit from a quick way back to the top instead of forcing a slow reverse scroll through everything already read.</p></section>
  <section class="block alt" id="s2"><h2>Section Two</h2><p>The button stays hidden until the user has scrolled past a threshold, so it never clutters the initial view of a short page.</p></section>
  <section class="block" id="s3"><h2>Section Three</h2><p>A smooth scroll animation on click feels more intentional than an instant jump, especially on pages with a lot of vertical distance to cover.</p></section>
  <section class="block alt" id="s4"><h2>Section Four</h2><p>Pair this with a scroll-progress indicator so returning users can tell at a glance how much of the page is left.</p></section>
  <button class="back-to-top" id="backToTop" onclick="scrollToTop()" aria-label="Back to top">
    <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
  </button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Fades and slides in using opacity, visibility, and transform — no JS animation loop
Single scroll listener compares window.scrollY against a configurable threshold constant
Native window.scrollTo({ behavior: "smooth" }) — no manual easing math required
visibility: hidden paired with opacity keeps the hidden button out of the tab order
Fixed bottom-right circular placement that stays clear of page content at any scroll position
Focus-visible outline for keyboard users tabbing to the button
Respects reduced-motion browser settings automatically via the native scroll API
One configurable constant (SHOW_AFTER) controls the entire show/hide behavior
Works on any page length or content type with no markup changes needed
No framework, no scroll library, no build step required

About this UI Snippet

Back to Top Button — HTML, CSS & JavaScript Scroll-to-Top Snippet

Screenshot of the Back to Top Button snippet rendered live

On long pages — articles, product listings, changelogs — users who scroll far down need a fast way back to the header without repeatedly flicking their mouse wheel or dragging a thumb across a phone screen. A back-to-top button solves this with a single fixed-position control that appears once it's actually useful and disappears when it isn't.

This snippet implements the full pattern in plain HTML, CSS, and vanilla JavaScript: a circular button fixed to the bottom-right corner, hidden by default, that fades and slides into view once the page has been scrolled past a threshold, and smooth-scrolls back to the top when clicked.

How the show/hide threshold works

A single scroll event listener on window checks window.scrollY against a SHOW_AFTER constant (400px by default). Past that point, the .visible class is added to the button; below it, the class is removed. The class itself does the animating — opacity, visibility, and a small transform: translateY all transition over 0.25s, so the button fades and slides up into place rather than snapping in abruptly. visibility: hidden is paired with opacity: 0 specifically so the invisible button can't be tabbed to or accidentally clicked while hidden.

How the smooth scroll works

The click handler is a single line: window.scrollTo({ top: 0, behavior: 'smooth' }). This uses the native Scroll Behavior API rather than a manual requestAnimationFrame loop or an interval that decrements scrollTop — the browser handles the easing curve itself, and it respects the user's OS-level "reduce motion" accessibility setting automatically in supporting browsers.

Why the threshold matters

Showing the button immediately at the top of the page is pointless — there's nowhere to scroll to. A 400px threshold roughly corresponds to "past the hero section" on most page layouts, so the button only appears once a user has actually scrolled far enough that jumping back up saves real effort. Tune SHOW_AFTER per page: a value close to one viewport height works well for most designs.

Performance note

The scroll listener here does very little work per tick — one comparison and a class toggle — so it doesn't need throttling for typical use. On extremely scroll-heavy pages with many other listeners, you can wrap the check in a requestAnimationFrame guard to avoid running it more than once per frame.

Step by step

How to Use

  1. 1
    Load the snippetClick "Back to Top Button" in the sidebar Library tab. The preview loads with a tall scrollable page and a hidden button.
  2. 2
    Scroll down in the previewScroll past the hero section — the circular arrow button fades and slides in from the bottom-right corner.
  3. 3
    Click the buttonClick it to trigger a native smooth scroll back to the top of the page, then watch the button fade back out.
  4. 4
    Adjust the thresholdIn the JS panel, change the SHOW_AFTER constant to control how far a user must scroll before the button appears.
  5. 5
    Restyle the buttonIn the CSS panel, update .back-to-top background, size, and position to match your site — bottom-left placement just needs left instead of right.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for React, or "Tailwind" for React + Tailwind CSS.

Real-world uses

Common Use Cases

SCROLL
Long-form articles and blog posts
Give readers a quick way back to the top of a long article without needing a sticky table of contents or manual scrolling.
Product listing and catalog pages
Let shoppers who have scrolled through dozens of products jump back to filters and search at the top instantly.
Learn threshold-based visibility toggling
Study how a single scrollY comparison combined with a CSS transition produces a clean, non-janky show/hide effect.
Match your brand and icon set
Swap the inline arrow SVG for your own icon and recolor the button to fit your site's design system.
Improve mobile scroll ergonomics
On touch devices where flicking back to the top repeatedly is tedious, a persistent tap target meaningfully improves navigation.
Port to a React or Vue component
Use the JSX export and replace the scroll listener with a useEffect hook that toggles a boolean state on scroll.
Related: Native CSS Scroll Progress Ring
See the Native CSS Scroll Progress Ring for a related scroll pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A scroll event listener on window checks window.scrollY against a SHOW_AFTER constant (400px by default). Once the user has scrolled past that point, a .visible class is added, which fades and slides the button into view via CSS transition.

Edit the SHOW_AFTER constant near the top of the JS panel. A larger number delays the button appearing until further down the page; a smaller number shows it sooner.

window.scrollTo with behavior: "smooth" is supported in all current major browsers. For very old browsers without support, the scroll simply happens instantly instead of animated — it still functions correctly, just without the easing.

Yes. In the CSS panel, replace right: 28px with left: 28px on .back-to-top. Everything else — the fade animation, the threshold logic — is unaffected by its horizontal position.

Only if they occupy the same corner. Move the button to a different corner, or add extra bottom/right spacing to stack it above another fixed element without overlapping.

Yes. It stays out of the tab order while hidden thanks to visibility: hidden, and once visible it is a normal focusable button with a visible focus-visible outline, so it works with keyboard-only and screen reader navigation.

Yes. Add an SVG circle stroke behind the arrow icon and update its stroke-dashoffset in the scroll listener proportionally to window.scrollY divided by the page's total scrollable height, turning the button into a scroll-progress indicator.

opacity: 0 alone still leaves the element clickable and focusable even though it is invisible. Pairing it with visibility: hidden removes it from the tab order and from hit-testing while hidden, then visibility: visible restores both once the .visible class is applied.