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

tech-stack-marquee

Бігучий рядок·Шаблон: Davies - Personal Portfolio HTML Template·Складність анімації: medium·Адаптивний: Так
tech-stack-marquee

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

  • index.htmlsection.section-tech-stack

Бібліотеки

jquery

Summary

A skill / tooling section disguised as a vertical accordion of three rows. Each row collapses to a label + percent. The active row expands to a full-width strip that runs an infinite marquee of duplicated label and logo pairs (Figma, Framer, Webflow). Only one row is active at a time, so animation cost stays bounded.

HTML structure (minimal)

<section class="section-tech-stack flat-spacing">
  <div class="container">
    <h6 class="mini-title text-caption text-white-64 text-center">TECH STACK</h6>
  </div>
  <ul class="tech-stack-list main-action-active">
    <li class="wg-tech btn-active active">
      <div class="tech_text">
        <p class="h1 fw-normal">Figma</p>
        <h6 class="fw-normal">96%</h6>
      </div>
      <div class="infiniteSlide_tech_main">
        <div class="infiniteSlide infiniteSlide_tech" data-clone="5">
          <div class="app_name"><div class="tech_text"><p class="h1 text">Figma</p><h6 class="process fw-normal">96%</h6></div></div>
          <div class="app_icon"><img src="assets/images/section/app-figma.png" alt=""></div>
          <!-- duplicated three times -->
        </div>
      </div>
    </li>
    <li class="wg-tech btn-active">…Framer 98%…</li>
    <li class="wg-tech btn-active">…Webflow 92%…</li>
  </ul>
</section>

Key SCSS tokens

.section-tech-stack {
  .wg-tech {
    border-top: 1px solid var(--white-16);
    overflow: hidden;
    height: 90px;
    transition: height 0.6s ease;

    .infiniteSlide_tech_main { opacity: 0; transition: opacity 0.4s ease; }

    &.active {
      height: 220px;
      .infiniteSlide_tech_main { opacity: 1; }
    }
  }
  .infiniteSlide_tech {
    display: flex;
    gap: 64px;
    align-items: center;
    will-change: transform;
  }
}

Animation logic

// assets/js/main.js — infiniteSlide()
$('.infiniteSlide').each(function () {
  var $this = $(this);
  var clone = $this.data('clone') || 2;
  var speed = $this.data('speed') || 50;
  // duplicates children N times then animates translateX with requestAnimationFrame at `speed` px/s.
});

// active row toggle is wired via .main-action-active in main.js — clicking another row swaps the .active class.

Notable details

  • Activation pattern: only one row is active at a time, so only one infinite marquee animates — saves repaint and battery on mobile compared to 3 simultaneous marquees.
  • The data-clone attribute lets each marquee duplicate its content N times in JS to ensure seamless wrap regardless of viewport width.
  • The label and percent in the marquee mirror the static label outside, reinforcing the active item without a separate cursor.

Use when

  • Skills / tooling lists where you want the hovered or active item to break free from the row and become a full-bleed strip.
  • Lists where keeping animation cost bounded matters (e.g. battery-conscious mobile portfolios).

Caveats

  • infinityslide.js is a small custom plugin shipped with the template — keep it bundled if you reuse this section.
  • The active row's height jump (90 → 220px) reflows neighbours; pair with will-change: height for smoother transitions.