How to Add a Sticky Back-to-Top Button to Your Website With CSS and JavaScript
A well-crafted back to top button is one of those tiny UX details that can dramatically improve navigation on long pages, blogs, documentation sites, and product listings. In this tutorial, we will build a lightweight, accessible, and smooth-scrolling back to top button using nothing more than plain HTML, CSS, and a few lines of JavaScript. No libraries, no bloat. By the end of this guide, you will have a production-ready snippet you can drop into any project, including Express.js views, static sites, WordPress themes, or single-page applications. What Is a Back to Top Button? A back to top button is a small floating control, typically anchored to the bottom-right corner of the viewport, that scrolls the user back to the top of the page when clicked. It usually appears only after the user has scrolled down a certain distance, keeping the interface clean when it is not needed. When Should You Use One? Long-form content such as blog posts, guides, and documentation Infinite scroll or lazy-loaded feeds Product listing pages with heavy filtering Mobile layouts where scrolling up manually is tedious If your page fits in one or two viewport heights, you probably do not need one. Reserve it for pages taller than roughly four screens. Step 1: Add the HTML We will use a real <button> element rather than a <div> or <a>. This matters for accessibility and keyboard navigation. <button id=”backToTop” class=”back-to-top” aria-label=”Scroll back to top” title=”Back to top”> <svg xmlns=”http://www.w3.org/2000/svg” width=”24″ height=”24″ viewBox=”0 0 24 24″ fill=”none” stroke=”currentColor” stroke-width=”2″ stroke-linecap=”round” stroke-linejoin=”round” aria-hidden=”true”> <path d=”M18 15l-6-6-6 6″/> </svg> </button> Place this markup right before your closing </body> tag so it stays out of the main document flow. Step 2: Style It With CSS The CSS handles positioning, appearance, and the smooth fade transition when the button appears or disappears. .back-to-top { position: fixed; bottom: 2rem; right: 2rem; width: 48px; height: 48px; border: none; border-radius: 50%; background-color: #0d6efd; color: #ffffff; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); opacity: 0; visibility: hidden; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s; z-index: 999; } .back-to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); } .back-to-top:hover, .back-to-top:focus-visible { background-color: #0b5ed7; outline: 2px solid #ffffff; outline-offset: 2px; } @media (prefers-reduced-motion: reduce) { .back-to-top { transition: opacity 0.2s ease; transform: none; } } Key CSS Choices Explained position: fixed keeps the button anchored while the user scrolls opacity + visibility creates a smooth fade without leaving an invisible click target focus-visible ensures keyboard users see a clear focus ring prefers-reduced-motion respects users who disable animations Step 3: Add the JavaScript We only need a small script to toggle the visible class and handle the scroll action. (function () { const button = document.getElementById(‘backToTop’); if (!button) return; const SCROLL_THRESHOLD = 300; // pixels let ticking = false; function updateButton() { if (window.scrollY > SCROLL_THRESHOLD) { button.classList.add(‘is-visible’); } else { button.classList.remove(‘is-visible’); } ticking = false; } window.addEventListener(‘scroll’, function () { if (!ticking) { window.requestAnimationFrame(updateButton); ticking = true; } }, { passive: true }); button.addEventListener(‘click’, function () { const prefersReducedMotion = window.matchMedia(‘(prefers-reduced-motion: reduce)’).matches; window.scrollTo({ top: 0, behavior: prefersReducedMotion ? ‘auto’ : ‘smooth’ }); }); })(); Why This Script Is Fast Uses requestAnimationFrame to throttle scroll events Uses a passive scroll listener so the browser can optimize scrolling performance Falls back to instant scroll when the user prefers reduced motion Wrapped in an IIFE to avoid polluting the global scope Accessibility Checklist A back to top button should be usable by everyone, not just mouse users. Here is what to verify before shipping: Concern Implementation Keyboard focus Use a native <button> element Screen readers Add aria-label=”Scroll back to top” Motion sensitivity Respect prefers-reduced-motion Focus after scroll Optionally move focus to the main heading Contrast Maintain at least 4.5:1 ratio for the icon Optional: Move Focus After Scrolling For screen reader users, scrolling visually to the top does not move the focus. You can improve this by focusing your main landmark after the scroll completes: button.addEventListener(‘click’, function () { window.scrollTo({ top: 0, behavior: ‘smooth’ }); const main = document.querySelector(‘main, h1’); if (main) { main.setAttribute(‘tabindex’, ‘-1’); main.focus({ preventScroll: true }); } }); Design Best Practices in 2026 Show it only when useful. Reveal after the user scrolls at least 300 to 500 pixels. Keep it small. Around 40 to 56 pixels wide, never dominating the viewport. Use a clear icon. An upward-pointing chevron or arrow is universally understood. Do not block content. On mobile, avoid overlapping call-to-action buttons or chat widgets. Match your brand. Use your primary color, but ensure contrast against varied backgrounds. Common Mistakes to Avoid Using an <a href=”#top”> without preventDefault, which pushes an entry into browser history Animating scroll with heavy JavaScript loops when window.scrollTo handles it natively Forgetting to test with keyboard-only navigation Placing the button over important interactive UI on small screens FAQ Do I need JavaScript for a back to top button? Not necessarily. A pure anchor link pointing to #top combined with scroll-behavior: smooth on the html element works without any JavaScript. However, JavaScript gives you control over when the button appears and how it behaves on reduced-motion systems. What is the ideal scroll distance before showing the button? Between 300 and 500 pixels works well for most sites. On very long articles, you might delay it further to avoid distraction during the first fold of reading. Is a back to top button good for SEO? Indirectly, yes. It improves dwell time and reduces friction on long pages, which can positively impact engagement metrics. It has no direct ranking factor, but better UX typically correlates with better rankings. Should the button appear on mobile? Yes, especially on mobile, where scrolling long articles is tedious. Just be careful not to cover sticky navigation bars, floating chat icons, or cookie banners. Can I use CSS scroll-behavior instead of JavaScript? Absolutely. Add html { scroll-behavior: smooth; } and link to an anchor at the top of the page. The trade-off is that you
How to Add a Sticky Back-to-Top Button to Your Website With CSS and JavaScript Read More »


