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

scroll-to-top

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

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

  • index.htmldiv.scroll-to-top

Бібліотеки

jquery

Summary

Bottom-right SVG circle that doubles as a scroll-to-top button. The circle's <path> is a 100×100 ring whose stroke-dashoffset shrinks as the page scrolls, giving a live progress indicator.

HTML structure (minimal)

<div class="scroll-to-top">
  <svg class="scroll-top-inner" viewBox="-1 -1 102 102">
    <path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98" />
  </svg>
</div>

Key SCSS tokens

.scroll-to-top {
  position: fixed; right: 30px; bottom: 30px;
  width: 50px; height: 50px;
  border-radius: 50%;
  background: rgba(0,0,0,0.05);
  cursor: pointer;
  opacity: 0; visibility: hidden; transform: scale(.8);
  transition: .3s;
  z-index: 99;
}
.scroll-to-top.open { opacity: 1; visibility: visible; transform: scale(1); }
.scroll-to-top svg path {
  fill: none;
  stroke: var(--theme-color);
  stroke-width: 4;
  stroke-dasharray: 307.919, 307.919;
  stroke-dashoffset: 307.919;
  transition: stroke-dashoffset .15s linear;
}

Animation logic

// scrolltop.min.js attaches a scroll handler that updates stroke-dashoffset
// based on scrollTop / scrollHeight, and toggles the .open class past 200 px.
$(window).on('scroll', function () {
  var s = $(window).scrollTop(), h = $(document).height() - $(window).height();
  var p = h ? s / h : 0;
  var len = 307.919;
  $('.scroll-to-top svg path').css('stroke-dashoffset', len * (1 - p));
  $('.scroll-to-top').toggleClass('open', s > 200);
});
$('.scroll-to-top').on('click', function () {
  $('html, body').animate({ scrollTop: 0 }, 600);
});

Notable details

  • The progress ring is a single <path> — no second background ring, no overlap, just stroke-dashoffset from the full perimeter (~307.92) down to 0.
  • Plays well with Lenis: the smooth-scroll updates the progress in real time because it dispatches normal scroll events.
  • Sized small (50 px) — doesn't compete with the custom cursor or the demo-switch.

Use when

  • Long single-page portfolios where the user benefits from a scroll-progress affordance.
  • Sites that already use scrolltop.min.js (or equivalent) and want a low-cost upgrade over a plain arrow.

Caveats

  • The dasharray length must match the path's actual perimeter (~307.919 for a 49 px-radius circle). If the path changes, recompute.
  • Hidden until past 200 px; the screenshot pipeline at 1440×900 lands above that, so this component captures as a palette-gradient placeholder.