Snippets Navigation

Bootstrap 5 Sticky Slider Navigation with Scroll Spy

A page layout with a sticky tab bar whose sliding indicator follows the section in view, and tabs that glide to their section.

Bootstrap 5 No jQuery Mar 2020 4.5K views

<div class="ssn" id="ssn">
  <header class="ssn-hero wdw-aurora d-flex align-items-center text-center">
    <div class="container py-4">
      <span class="badge rounded-pill bg-white bg-opacity-10 text-white border border-white border-opacity-25 mb-3">Scroll spy</span>
      <h1 class="display-4 fw-bolder mb-3">Sticky slider navigation</h1>
      <p class="fs-5 mx-auto mb-0 opacity-75" style="max-width:34rem">Sliding content with a tab bar that sticks to the top and follows you down the page.</p>
    </div>
  </header>
  <nav class="ssn-bar" aria-label="Page sections" id="ssnBar">
    <div class="container">
      <div class="ssn-mask"><ul class="nav ssn-nav position-relative flex-nowrap" id="ssnNav">
        <li class="ssn-slider" id="ssnSlider" aria-hidden="true"></li>
        <li class="nav-item"><a class="nav-link ssn-link active" href="#ssn-overview" aria-current="true">Overview</a></li><li class="nav-item"><a class="nav-link ssn-link" href="#ssn-features">Features</a></li><li class="nav-item"><a class="nav-link ssn-link" href="#ssn-pricing">Pricing</a></li><li class="nav-item"><a class="nav-link ssn-link" href="#ssn-faq">FAQ</a></li><li class="nav-item"><a class="nav-link ssn-link" href="#ssn-contact">Contact</a></li>
      </ul></div>
    </div>
  </nav>
  <main>
    <section id="ssn-overview" class="ssn-section"><div class="container" style="max-width:820px"><div class="mb-4"><span class="wdw-eyebrow">Overview</span><h2 class="wdw-heading display-6 mt-1 mb-2">Everything in one scroll</h2><p class="fs-5 wdw-muted mb-0" style="max-width:36rem">A single page where each section has its own tab. Scroll and the pill follows you; click a tab and the page glides to it.</p></div><div class="row g-3"><div class="col-4"><div class="wdw-card-sm p-3 text-center"><div class="h3 fw-bolder text-primary mb-0">5</div><div class="small wdw-muted">Sections</div></div></div><div class="col-4"><div class="wdw-card-sm p-3 text-center"><div class="h3 fw-bolder text-primary mb-0">1</div><div class="small wdw-muted">Sticky bar</div></div></div><div class="col-4"><div class="wdw-card-sm p-3 text-center"><div class="h3 fw-bolder text-primary mb-0">0</div><div class="small wdw-muted">Extra libraries</div></div></div></div></div></section>
    <section id="ssn-features" class="ssn-section"><div class="container" style="max-width:820px"><div class="mb-4"><span class="wdw-eyebrow">Features</span><h2 class="wdw-heading display-6 mt-1 mb-2">Built for real pages</h2><p class="fs-5 wdw-muted mb-0" style="max-width:36rem">Sticky positioning, scroll spy and a sliding indicator, in a handful of lines.</p></div><div class="row g-3"><div class="col-md-4"><div class="wdw-card-sm p-4 h-100"><span class="wdw-icon mb-3"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.85" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v18M5 10l7-7 7 7"/></svg></span><h3 class="h6 mb-1">Sticky positioning</h3><p class="small wdw-muted mb-0">The bar pins to the top of the viewport the moment you scroll past the hero.</p></div></div><div class="col-md-4"><div class="wdw-card-sm p-4 h-100"><span class="wdw-icon mb-3"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.85" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg></span><h3 class="h6 mb-1">Live scroll spy</h3><p class="small wdw-muted mb-0">Bootstrap ScrollSpy marks the section in view and keeps the tab in sync.</p></div></div><div class="col-md-4"><div class="wdw-card-sm p-4 h-100"><span class="wdw-icon mb-3"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.85" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 12h16M14 6l6 6-6 6"/></svg></span><h3 class="h6 mb-1">Sliding indicator</h3><p class="small wdw-muted mb-0">A pill glides between tabs, so you always see where you are on the page.</p></div></div></div></div></section>
    <section id="ssn-pricing" class="ssn-section"><div class="container" style="max-width:820px"><div class="mb-4"><span class="wdw-eyebrow">Pricing</span><h2 class="wdw-heading display-6 mt-1 mb-2">Simple, honest plans</h2><p class="fs-5 wdw-muted mb-0" style="max-width:36rem">Start free, upgrade when you grow. No setup fees and no surprises on the invoice.</p></div><div class="row g-3"><div class="col-md-4"><div class="wdw-card-sm p-4 h-100 d-flex flex-column"><h3 class="h6 mb-1">Starter</h3><p class="small wdw-muted">For side projects</p><div class="mb-3"><span class="display-6 fw-bolder text-body-emphasis">$0</span><span class="wdw-muted"> /mo</span></div><ul class="list-unstyled small mb-4"><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>1 project</li><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Community support</li></ul><button type="button" class="btn btn-outline-primary rounded-pill mt-auto">Choose Starter</button></div></div><div class="col-md-4"><div class="wdw-card-sm p-4 h-100 d-flex flex-column border-primary border-2"><h3 class="h6 mb-1">Pro <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis ms-1">Popular</span></h3><p class="small wdw-muted">For growing teams</p><div class="mb-3"><span class="display-6 fw-bolder text-body-emphasis">$19</span><span class="wdw-muted"> /mo</span></div><ul class="list-unstyled small mb-4"><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Unlimited projects</li><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Priority support</li><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Custom domains</li></ul><button type="button" class="btn btn-primary rounded-pill mt-auto">Choose Pro</button></div></div><div class="col-md-4"><div class="wdw-card-sm p-4 h-100 d-flex flex-column"><h3 class="h6 mb-1">Scale</h3><p class="small wdw-muted">For busy products</p><div class="mb-3"><span class="display-6 fw-bolder text-body-emphasis">$49</span><span class="wdw-muted"> /mo</span></div><ul class="list-unstyled small mb-4"><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Everything in Pro</li><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>SSO and audit logs</li><li class="d-flex gap-2 mb-2"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="text-primary flex-shrink-0 mt-1" aria-hidden="true"><path d="M5 12l5 5 9-10"/></svg>Dedicated manager</li></ul><button type="button" class="btn btn-outline-primary rounded-pill mt-auto">Choose Scale</button></div></div></div></div></section>
    <section id="ssn-faq" class="ssn-section"><div class="container" style="max-width:820px"><div class="mb-4"><span class="wdw-eyebrow">FAQ</span><h2 class="wdw-heading display-6 mt-1 mb-2">Questions answered</h2><p class="fs-5 wdw-muted mb-0" style="max-width:36rem">Quick answers to the things people ask before they ship.</p></div><div class="accordion wdw-card-sm overflow-hidden" id="ssnFaq"><div class="accordion-item"><h3 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#ssnQ0" aria-expanded="true" aria-controls="ssnQ0">Do I need a plugin?</button></h3><div id="ssnQ0" class="accordion-collapse collapse show" data-bs-parent="#ssnFaq"><div class="accordion-body wdw-muted">No. The component uses Bootstrap ScrollSpy and a few lines of vanilla JavaScript.</div></div></div><div class="accordion-item"><h3 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#ssnQ1" aria-expanded="false" aria-controls="ssnQ1">Can I change the sections?</button></h3><div id="ssnQ1" class="accordion-collapse collapse" data-bs-parent="#ssnFaq"><div class="accordion-body wdw-muted">Yes. Add a link in the nav and a section with a matching id; the spy picks it up.</div></div></div><div class="accordion-item"><h3 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#ssnQ2" aria-expanded="false" aria-controls="ssnQ2">Does it work on phones?</button></h3><div id="ssnQ2" class="accordion-collapse collapse" data-bs-parent="#ssnFaq"><div class="accordion-body wdw-muted">The tab bar scrolls sideways on narrow screens and keeps the active tab in view.</div></div></div></div></div></section>
    <section id="ssn-contact" class="ssn-section"><div class="container" style="max-width:820px"><div class="mb-4"><span class="wdw-eyebrow">Contact</span><h2 class="wdw-heading display-6 mt-1 mb-2">Say hello</h2><p class="fs-5 wdw-muted mb-0" style="max-width:36rem">Tell us what you are building and we will point you to the right starting place.</p></div>
      <form class="wdw-card p-4" onsubmit="return false"><div class="row g-3"><div class="col-md-6"><label class="form-label small fw-semibold" for="ssnName">Name</label><input class="form-control" id="ssnName" autocomplete="name"></div><div class="col-md-6"><label class="form-label small fw-semibold" for="ssnMail">Email</label><input type="email" class="form-control" id="ssnMail" autocomplete="email"></div><div class="col-12"><label class="form-label small fw-semibold" for="ssnMsg">Message</label><textarea class="form-control ssn-msg" id="ssnMsg" rows="3"></textarea></div><div class="col-12"><button type="submit" class="btn btn-primary rounded-pill px-4">Send message</button></div></div></form>
    </div></section>
  </main>
</div>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.