Skip to main content
Settings
Search
Appearance
Theme Mode
About
Jekyll v3.10.0
Environment Production
Last Build
2026-05-19 04:06 UTC
Current Environment Production
Build Time May 19, 04:06
Jekyll v3.10.0
Build env (JEKYLL_ENV) production
Page Location
Page Info
Layout default
Collection docs
Path _docs/features/back-to-top.md
URL /docs/features/back-to-top/
Date 2026-05-19
Theme Skin
SVG Backgrounds
Layer Opacity
0.6
0.04
0.08

Back to Top Button

A floating button that appears when users scroll down, providing quick navigation back to the top of the page.

Overview

  • Appears on Scroll: Shows after scrolling 200px
  • Smooth Animation: Animated scroll to top
  • Accessible: Proper button semantics
  • Performance: Passive scroll listener

Implementation

HTML Markup

<button id="backToTopBtn" 
        class="btn btn-primary rounded-circle position-fixed"
        aria-label="Back to top"
        style="bottom: 20px; right: 20px; display: none; z-index: 1000;">
  <i class="bi bi-arrow-up"></i>
</button>

JavaScript

document.addEventListener('DOMContentLoaded', () => {
  const btn = document.getElementById('backToTopBtn');
  if (!btn) return;

  // Scroll to top
  btn.addEventListener('click', (e) => {
    e.preventDefault();
    window.scrollTo({ top: 0, behavior: 'smooth' });
  });

  // Show/hide based on scroll position
  const toggle = () => {
    const y = window.scrollY || document.documentElement.scrollTop;
    btn.style.display = y > 200 ? 'block' : 'none';
  };

  toggle();
  window.addEventListener('scroll', toggle, { passive: true });
});

Configuration

Scroll Threshold

Adjust when button appears:

// Show after scrolling 500px
btn.style.display = y > 500 ? 'block' : 'none';

Position

#backToTopBtn {
  bottom: 20px;  /* Distance from bottom */
  right: 20px;   /* Distance from right */
}

/* Or use Bootstrap utilities */
.back-to-top {
  bottom: 1rem;
  right: 1rem;
}

Styling

#backToTopBtn {
  width: 48px;
  height: 48px;
  background-color: var(--bs-primary);
  border: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  transition: opacity 0.3s ease;
}

#backToTopBtn:hover {
  background-color: var(--bs-primary-dark);
  transform: translateY(-2px);
}

Customization

Different Icons

<!-- Arrow up -->
<i class="bi bi-arrow-up"></i>

<!-- Chevron up -->
<i class="bi bi-chevron-up"></i>

<!-- Caret up -->
<i class="bi bi-caret-up-fill"></i>

With Text

<button id="backToTopBtn" class="btn btn-primary">
  <i class="bi bi-arrow-up me-1"></i>
  Top
</button>

Fade Animation

#backToTopBtn {
  opacity: 0;
  transition: opacity 0.3s ease;
}

#backToTopBtn.visible {
  opacity: 1;
}
btn.classList.toggle('visible', y > 200);

Accessibility

ARIA Attributes

<button aria-label="Scroll to top of page"
        role="button"
        tabindex="0">

Focus Visible

#backToTopBtn:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
}

Keyboard Support

The button is focusable and activates with Enter/Space.

Performance

Passive Listener

window.addEventListener('scroll', toggle, { passive: true });

The passive: true option improves scroll performance by indicating the listener won’t call preventDefault().

Debouncing (Optional)

For heavy pages, debounce the scroll handler:

function debounce(fn, wait) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(fn, wait);
  };
}

window.addEventListener('scroll', debounce(toggle, 100), { passive: true });

Mobile Considerations

Touch-Friendly Size

Ensure button meets minimum tap target (44x44px):

#backToTopBtn {
  width: 48px;
  height: 48px;
  min-width: 44px;
  min-height: 44px;
}

Avoid Overlap

Position to not interfere with mobile TOC button:

/* When mobile TOC FAB is present */
@media (max-width: 991px) {
  #backToTopBtn {
    bottom: 80px; /* Above TOC button */
  }
}

Troubleshooting

Button Not Appearing

  1. Check scroll threshold
  2. Verify element exists in DOM
  3. Check z-index conflicts
  4. Inspect display style

Not Scrolling

  1. Verify behavior: 'smooth' support
  2. Check for scroll lock on body
  3. Test without other scroll scripts

Performance Issues

  1. Add passive listener option
  2. Use debouncing
  3. Reduce scroll threshold checks

See also

  • [[Features]]
  • [[Keyboard Navigation]]
  • [[Mobile TOC Floating Action Button]]