Snippets Menu

Bootstrap 5 Vertical Icon Navigation Sidebar

A single-page layout with a slim icon rail that switches between full sections, with tooltips, arrow-key navigation and a bottom bar on phones.

Bootstrap 5 No jQuery Jun 2019 3.6K views

<section class="wdw-stage">
  <div class="container" style="max-width: 980px">
    <div class="wdw-card onav overflow-hidden d-flex flex-column flex-md-row">
      <ul class="onav-rail nav nav-pills flex-md-column flex-nowrap justify-content-around justify-content-md-start gap-md-2 p-2 p-md-3 order-2 order-md-1" id="onavTabs" role="tablist" aria-orientation="vertical">
        <li class="nav-item onav-item" role="presentation" data-bs-title="Overview"><button class="onav-tab nav-link active" id="tab-overview" data-bs-toggle="pill" data-bs-target="#panel-overview" type="button" role="tab" aria-controls="panel-overview" aria-selected="true" aria-label="Overview"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg></button></li>
        <li class="nav-item onav-item" role="presentation" data-bs-title="Write"><button class="onav-tab nav-link" id="tab-write" data-bs-toggle="pill" data-bs-target="#panel-write" type="button" role="tab" aria-controls="panel-write" aria-selected="false" aria-label="Write"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></button></li>
        <li class="nav-item onav-item" role="presentation" data-bs-title="Launch"><button class="onav-tab nav-link" id="tab-launch" data-bs-toggle="pill" data-bs-target="#panel-launch" type="button" role="tab" aria-controls="panel-launch" aria-selected="false" aria-label="Launch"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 15c-1.5 1.3-2 5-2 5s3.7-.5 5-2c.7-.8.7-2.1-.1-2.9S5.8 14.3 5 15Z"/><path d="m12 15-3-3a22 22 0 0 1 2-4 12.4 12.4 0 0 1 11-5c0 2.7-.8 7.5-5 11a22 22 0 0 1-4 2Z"/></svg></button></li>
        <li class="nav-item onav-item" role="presentation" data-bs-title="Showcase"><button class="onav-tab nav-link" id="tab-showcase" data-bs-toggle="pill" data-bs-target="#panel-showcase" type="button" role="tab" aria-controls="panel-showcase" aria-selected="false" aria-label="Showcase"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></button></li>
        <li class="nav-item onav-item" role="presentation" data-bs-title="More"><button class="onav-tab nav-link" id="tab-more" data-bs-toggle="pill" data-bs-target="#panel-more" type="button" role="tab" aria-controls="panel-more" aria-selected="false" aria-label="More"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v8M8 12h8"/></svg></button></li>
      </ul>

      <div class="onav-stage tab-content flex-grow-1 order-1 order-md-2">
        <section class="tab-pane fade show active onav-panel" role="tabpanel" id="panel-overview" aria-labelledby="tab-overview" tabindex="0">
          <div class="d-flex align-items-center gap-3 mb-3"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg></span><div><h2 class="wdw-heading h3 mb-0">Overview</h2><p class="wdw-muted small mb-0">Your week at a glance</p></div></div>
          <div class="row g-3">
            <div class="col-12 col-lg-7"><div class="wdw-card-sm p-3 h-100"><div class="d-flex justify-content-between align-items-baseline mb-2"><span class="fw-semibold">Visitors</span><span class="small text-success fw-semibold">+12.4%</span></div><div class="h2 fw-bold mb-3">8,420</div><div class="onav-chart d-flex align-items-end gap-2" role="img" aria-label="Bar chart of visitors, rising through the week"><div class="onav-bar rounded-top" style="height:38%"></div><div class="onav-bar rounded-top" style="height:55%"></div><div class="onav-bar rounded-top" style="height:42%"></div><div class="onav-bar rounded-top" style="height:70%"></div><div class="onav-bar rounded-top" style="height:62%"></div><div class="onav-bar rounded-top" style="height:88%"></div><div class="onav-bar rounded-top" style="height:76%"></div></div><div class="d-flex justify-content-between small wdw-muted mt-2" aria-hidden="true"><span>Mon</span><span>Wed</span><span>Fri</span><span>Sun</span></div></div></div>
            <div class="col-12 col-lg-5"><div class="wdw-card-sm p-3 h-100"><span class="fw-semibold d-block mb-1">Recent activity</span><ul class="list-group list-group-flush"><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">A</span><div class="min-w-0"><div class="fw-semibold">New comment</div><div class="small wdw-muted">Alex on Launch notes</div></div></li><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">B</span><div class="min-w-0"><div class="fw-semibold">Post published</div><div class="small wdw-muted">Design notes</div></div></li><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">C</span><div class="min-w-0"><div class="fw-semibold">3 new followers</div><div class="small wdw-muted">Today</div></div></li></ul></div></div>
          </div>
        </section>
        <section class="tab-pane fade onav-panel" role="tabpanel" id="panel-write" aria-labelledby="tab-write" tabindex="0">
          <div class="d-flex align-items-center gap-3 mb-3"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></span><div><h2 class="wdw-heading h3 mb-0">Write</h2><p class="wdw-muted small mb-0">Drafts and notes, one tap away</p></div></div><ul class="list-group list-group-flush"><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">1</span><div class="min-w-0"><div class="fw-semibold">Launch announcement</div><div class="small wdw-muted">Edited 2 hours ago</div></div></li><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">2</span><div class="min-w-0"><div class="fw-semibold">Design notes</div><div class="small wdw-muted">Edited yesterday</div></div></li><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">3</span><div class="min-w-0"><div class="fw-semibold">Release checklist</div><div class="small wdw-muted">Edited 3 days ago</div></div></li><li class="list-group-item bg-transparent d-flex gap-3 align-items-center px-0"><span class="wdw-icon flex-shrink-0">4</span><div class="min-w-0"><div class="fw-semibold">Weekly newsletter</div><div class="small wdw-muted">Edited last week</div></div></li></ul>
        </section>
        <section class="tab-pane fade onav-panel" role="tabpanel" id="panel-launch" aria-labelledby="tab-launch" tabindex="0">
          <div class="d-flex align-items-center gap-3 mb-3"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 15c-1.5 1.3-2 5-2 5s3.7-.5 5-2c.7-.8.7-2.1-.1-2.9S5.8 14.3 5 15Z"/><path d="m12 15-3-3a22 22 0 0 1 2-4 12.4 12.4 0 0 1 11-5c0 2.7-.8 7.5-5 11a22 22 0 0 1-4 2Z"/></svg></span><div><h2 class="wdw-heading h3 mb-0">Launch</h2><p class="wdw-muted small mb-0">Ready to ship? Check the list and go live.</p></div></div><div class="wdw-card-sm p-3 p-md-4"><div class="progress mb-2" style="height: 8px" role="progressbar" aria-label="Launch checklist" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"><div class="progress-bar" style="width: 75%"></div></div><p class="small wdw-muted mb-3">3 of 4 checklist items done</p>
            <div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="l1" checked disabled><label class="form-check-label" for="l1">Copy reviewed</label></div>
            <div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="l2" checked disabled><label class="form-check-label" for="l2">Images optimised</label></div>
            <div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="l3" checked disabled><label class="form-check-label" for="l3">Analytics connected</label></div>
            <div class="form-check mb-4"><input class="form-check-input" type="checkbox" id="l4" disabled><label class="form-check-label" for="l4">Domain verified</label></div>
            <button type="button" class="btn btn-primary rounded-pill px-4">Go live</button></div>
        </section>
        <section class="tab-pane fade onav-panel" role="tabpanel" id="panel-showcase" aria-labelledby="tab-showcase" tabindex="0">
          <div class="d-flex align-items-center gap-3 mb-3"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg></span><div><h2 class="wdw-heading h3 mb-0">Showcase</h2><p class="wdw-muted small mb-0">Recent work, ready to share</p></div></div><div class="row g-2 g-md-3"><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 1" loading="lazy" class="object-fit-cover"></div></div><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 2" loading="lazy" class="object-fit-cover"></div></div><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 3" loading="lazy" class="object-fit-cover"></div></div><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 4" loading="lazy" class="object-fit-cover"></div></div><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 5" loading="lazy" class="object-fit-cover"></div></div><div class="col-4"><div class="ratio ratio-1x1 rounded-3 overflow-hidden bg-body-secondary"><img src="https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?auto=format&fit=crop&w=240&h=240&q=70" alt="Showcase photo 6" loading="lazy" class="object-fit-cover"></div></div></div>
        </section>
        <section class="tab-pane fade onav-panel" role="tabpanel" id="panel-more" aria-labelledby="tab-more" tabindex="0">
          <div class="d-flex align-items-center gap-3 mb-3"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v8M8 12h8"/></svg></span><div><h2 class="wdw-heading h3 mb-0">More</h2><p class="wdw-muted small mb-0">Add as many sections as your page needs</p></div></div><p class="wdw-muted">Use the arrow keys to move between sections. Each icon shows its label on hover or focus.</p><div class="d-flex flex-wrap gap-2 mb-4"><span class="badge rounded-pill bg-primary-subtle text-primary-emphasis px-3 py-2">Keyboard friendly</span><span class="badge rounded-pill bg-primary-subtle text-primary-emphasis px-3 py-2">Tooltips</span><span class="badge rounded-pill bg-primary-subtle text-primary-emphasis px-3 py-2">Responsive rail</span></div>
          <div class="wdw-card-sm p-3 d-flex gap-3 align-items-center"><span class="wdw-icon">+</span><div><div class="fw-semibold">Add a section</div><div class="small wdw-muted">Duplicate a tab button and its pane.</div></div></div>
        </section>
      </div>
    </div>
  </div>
</section>

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

Free to use in personal and commercial projects under the MIT license.