Nahorniak Templates
База референсів шаблонів і компонентів
Назад до шаблону · Davies - Personal Portfolio HTML Template
c103

scroll-progress-button

Інтерактив·Шаблон: Davies - Personal Portfolio HTML Template·Складність анімації: subtle·Адаптивний: Так
scroll-progress-button

Файли-джерела

  • index.htmlbutton#goTop

Бібліотеки

jquery

Summary

Floating bottom-right "Go to top" button with a circular progress ring that fills as the user scrolls. Inside the ring is a chevron icon. The ring is drawn with a conic-gradient whose angle is updated from JS based on scroll percentage.

HTML structure (minimal)

<button id="goTop">
  <span class="border-progress"></span>
  <span class="ic-wrap">
    <span class="icon icon-arrow-caret-right"></span>
  </span>
</button>

Key SCSS tokens

#goTop {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--white);
  border: 0;
  z-index: 100;
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.3s ease, transform 0.3s ease;

  &.show {
    opacity: 1;
    transform: translateY(0);
  }

  .border-progress {
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    background: conic-gradient(var(--primary) var(--progress, 0deg), transparent 0);
    -webkit-mask: radial-gradient(circle at center, transparent 28px, #000 28px);
            mask: radial-gradient(circle at center, transparent 28px, #000 28px);
  }

  .ic-wrap .icon { transform: rotate(-90deg); }
}

Animation logic

// assets/js/main.js — goTop()
$(window).on('scroll', function () {
  var scrollTop = $(window).scrollTop();
  var docHeight = $(document).height() - $(window).height();
  var scrollPercent = (scrollTop / docHeight) * 100;
  var progressAngle = (scrollPercent / 100) * 360;
  $borderProgress.css('--progress', progressAngle + 'deg');

  if (scrollTop > 200) $goTop.addClass('show');
  else $goTop.removeClass('show');
});

$goTop.on('click', function () {
  gsap.to(window, { duration: 1, scrollTo: 0, ease: 'power2.out' });
});

Notable details

  • Conic-gradient + radial mask creates a clean ring without an SVG — cheaper to repaint and easier to colour-theme via the --primary custom property.
  • The progress angle is written to a CSS custom property (--progress) instead of touching inline style every frame — the browser handles interpolation.
  • Hides itself when within 200px of the top, also fades out near the footer (the JS additionally checks for footer overlap to avoid stacking with the back-to-top link).

Use when

  • Long-scroll single-page sites where users benefit from a visual indicator of where they are.
  • Brand themes that already have a primary CSS variable — the ring re-themes for free.

Caveats

  • The radial-mask fallback for older Safari (pre 15.4) is missing — add -webkit-mask (already present) and consider an SVG fallback for legacy browsers.
  • The scroll listener is not throttled; on long pages or low-power devices, swap to ScrollTrigger.update or rAF throttling.