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

mobile-offcanvas-menu

Сайдбар·Шаблон: Davies - Personal Portfolio HTML Template·Складність анімації: medium·Адаптивний: Так
mobile-offcanvas-menu

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

  • index.htmldiv.offcanvas-menu

Бібліотеки

jquery

Summary

Full-height offcanvas drawer that slides in when the header MENU button is tapped. Each link is rendered as a display-1 sized headline; alongside the label, a horizontal infiniteSlide strip runs an endless "// View [Section]" caption. The footer of the drawer carries the email + clock and a row of social links.

HTML structure (minimal)

<div class="offcanvas-menu">
  <div class="offcanvas-content">
    <div class="container h-100">
      <div class="offcanvas-content_wrapin">
        <div class="canvas_head">
          <a href="index.html" class="logo-site"><i class="icon icon-davies-logo"></i></a>
          <div class="btn-mobile-menu close-mb-menu text-caption link">
            <i class="icon icon-close"></i> CLOSE
          </div>
        </div>
        <div class="canvas_center">
          <ul class="nav-ul-mb">
            <li>
              <div class="item close-mb-menu">
                <a href="#workScroll" class="mb-menu-link text-display-1">
                  <span class="text">Works</span>
                  <div class="infiniteSlide_text_main">
                    <div class="infiniteSlide infiniteSlide_text" data-clone="5">
                      <p class="text-body-2"><span class="text-primary">//</span> View Works</p>
                      <p class="text-body-2"><span class="text-primary">//</span> View Works</p>
                      <p class="text-body-2"><span class="text-primary">//</span> View Works</p>
                    </div>
                  </div>
                </a>
              </div>
            </li>
            <!-- About / Services / Contact -->
          </ul>
        </div>
        <div class="canvas_foot">
          <div class="left">
            <a href="mailto:davies@gmail.com" class="link text-caption">DAVIES@GMAIL.COM</a>
            <p class="text-caption">CUP <span class="clock"></span></p>
          </div>
          <div class="right">
            <a href="#" class="tf-link-icon text-caption link"><i class="icon icon-arrow-top-right"></i> TWITTER (X)</a>
            <a href="#" class="tf-link-icon text-caption link"><i class="icon icon-arrow-top-right"></i> DRIBBBLE</a>
            <a href="#" class="tf-link-icon text-caption link"><i class="icon icon-arrow-top-right"></i> LINKEDIN</a>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Key SCSS tokens

.offcanvas-menu {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--black);
  transform: translateY(-100%);
  transition: transform 0.6s cubic-bezier(0.86, 0, 0.07, 1);

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

  .offcanvas-content_wrapin {
    display: grid;
    grid-template-rows: auto 1fr auto;
    height: 100%;
    padding: 24px 0;
  }

  .mb-menu-link {
    display: flex;
    align-items: baseline;
    gap: 24px;
    padding: 24px 0;
    border-bottom: 1px solid var(--white-16);
    overflow: hidden;
  }

  .infiniteSlide_text_main {
    flex: 1;
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent 0, #000 10%, #000 90%, transparent 100%);
  }
}

Animation logic

// assets/js/main.js — openMbMenu()
$('.open-mb-menu').on('click', () => $('.offcanvas-menu').addClass('show'));
$('.close-mb-menu').on('click', () => $('.offcanvas-menu').removeClass('show'));
// infiniteSlide() runs across the whole page; the strips inside the drawer use the same loop.

Notable details

  • Each link row is its own infiniteSlide with data-clone="5" — the duplicates are necessary because the drawer is full width on mobile, so the natural content count is too small to wrap seamlessly.
  • A linear-gradient mask on .infiniteSlide_text_main fades both edges of the strip — visually cleaner than abrupt cut-offs.
  • The drawer reuses the same .clock updater as the header — a single setInterval updates both clocks at once.

Use when

  • Mobile menus where you want the menu links to feel like editorial titles rather than a conventional nav list.
  • Drawers that should slide from the top to feel like the header expanding rather than a side panel.

Caveats

  • The drawer is hidden on first paint (transform: translateY(-100%)); the screenshot pipeline will fall back to a placeholder.
  • Each row's infiniteSlide runs continuously even when the drawer is closed unless paused. Consider pausing on .offcanvas-menu:not(.show) for battery on mobile.