Skip to content

bootstrap_ref_js_scrollspy

The Scrollspy plugin dynamically updates links in a navigation list based on the current scroll position on the page. This is useful for single-page designs or pages with clear sections that users can navigate to.

Note: Scrollspy requires Bootstrap’s JavaScript and Popper.js (which is included in Bootstrap’s bundle: bootstrap.bundle.min.js). It also requires the navigation component to have position: sticky; or position: fixed; for the spy effect to be clearly visible while scrolling.

To easily add scrollspy behavior, add data-bs-spy="scroll" to the element you want to spy on (often the <body> element). Then, add data-bs-target with the ID or class of the navigation component (e.g., a <nav> or <ul>). Ensure that the scrollable element has a defined height and overflow-y: scroll; if it’s not the <body>.

The href attributes in your navigation links must match the id attributes of the sections you want to spy on.

<!-- Navigation Bar -->
<nav id="navbar-example" class="navbar navbar-light bg-light px-3 sticky-top">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading1">First</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2">Second</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#scrollspyHeading3">Third</a></li>
<li><a class="dropdown-item" href="#scrollspyHeading4">Fourth</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#scrollspyHeading5">Fifth</a></li>
</ul>
</li>
</ul>
</nav>
<!-- Scrollable Area -->
<div data-bs-spy="scroll" data-bs-target="#navbar-example" data-bs-offset="0" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0" style="position: relative; height: 200px; overflow-y: scroll;">
<h4 id="scrollspyHeading1">First heading</h4>
<p>Content for first heading...</p>
<h4 id="scrollspyHeading2">Second heading</h4>
<p>Content for second heading...</p>
<h4 id="scrollspyHeading3">Third heading</h4>
<p>Content for third heading...</p>
<h4 id="scrollspyHeading4">Fourth heading</h4>
<p>Content for fourth heading...</p>
<h4 id="scrollspyHeading5">Fifth heading</h4>
<p>Content for fifth heading...</p>
</div>

Key attributes: data-bs-spy="scroll", data-bs-target="#navbar-example", data-bs-offset="value" (pixels to offset from top when calculating scroll position), and data-bs-smooth-scroll="true" for animated scrolling when nav links are clicked.

You can also initialize Scrollspy manually with JavaScript:

var scrollSpy = new bootstrap.ScrollSpy(document.body, {
target: '#navbar-example'
});
// Or on a specific scrollable element:
var dataSpyList = [].slice.call(document.querySelectorAll('[data-bs-spy="scroll"]'))
dataSpyList.forEach(function (dataSpyEl) {
bootstrap.ScrollSpy.getInstance(dataSpyEl)
.refresh()
});

Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-bs-, as in data-bs-offset="50".

NameTypeDefaultDescription
offsetnumber10Specifies the number of pixels to offset from the top when calculating the scroll position. Useful if you have a fixed header.
targetstring | ElementnullSpecifies the target navigation element (ID or class selector) whose links will be updated.
smoothScrollbooleanfalseEnables smooth scrolling when a navigation link is clicked. Set via data-bs-smooth-scroll="true".

These methods allow programmatic control over the Scrollspy instance.

Method
Description
Example
.refresh()
When dynamically adding or removing items from the DOM that affect scrollspy targets, call this method to update the Scrollspy instance. `bootstrap.ScrollSpy.getInstance(element).refresh()`
Try it
.dispose()
Destroys an element’s scrollspy. `bootstrap.ScrollSpy.getInstance(element).dispose()`
Try it
.getInstance(element)
Static method which allows you to get the scrollspy instance associated with a DOM element. `var scrollSpyInstance = bootstrap.ScrollSpy.getInstance(myScrollspyElement)`
Try it
.getOrCreateInstance(element, [config])
Static method which allows you to get the scrollspy instance associated with a DOM element, or create a new one in case it wasn’t initialized. `var scrollSpyInstance = bootstrap.ScrollSpy.getOrCreateInstance(myScrollspyElement, {offset: 20})`
Try it

Bootstrap’s Scrollspy plugin exposes one event that you can hook into.

Event
Description
Example
activate.bs.scrollspy
This event fires on the navigation list whenever a new item becomes activated by the scrollspy. The event provides `relatedTarget` property which is the ID of the activated section. `myScrollSpyElement.addEventListener('activate.bs.scrollspy', function (event) { console.log('Active section:', event.relatedTarget); })`
Try it

Application Scenario: A product landing page with sections like ‘Features’, ‘Specifications’, ‘Pricing’, and ‘Contact’. A sticky navigation bar at the top uses Scrollspy to highlight the current section link as the user scrolls, and clicking a link smoothly scrolls to that section.

Common Pitfall: Ensure your target sections (e.g., <div id="section1">) have enough content to be scrollable and for their top to pass the scrollspy offset. If sections are too short, Scrollspy might not activate correctly.