
- Bootstrap Tutorial
- Bootstrap - Home
- Bootstrap - Overview
- Bootstrap - Environment Setup
- Bootstrap - RTL
- Bootstrap - CSS Variables
- Bootstrap - Color Modes
- Bootstrap Layouts
- Bootstrap - Breakpoints
- Bootstrap - Containers
- Bootstrap - Grid System
- Bootstrap - Columns
- Bootstrap - Gutters
- Bootstrap - Utilities
- Bootstrap - Z-index
- Bootstrap - CSS Grid
- Bootstrap Content
- Bootstrap - Reboot
- Bootstrap - Typography
- Bootstrap - Images
- Bootstrap - Tables
- Bootstrap - Figures
- Bootstrap Components
- Bootstrap - Accordion
- Bootstrap - Alerts
- Bootstrap - Badges
- Bootstrap - Breadcrumb
- Bootstrap - Buttons
- Bootstrap - Button Groups
- Bootstrap - Cards
- Bootstrap - Carousel
- Bootstrap - Close button
- Bootstrap - Collapse
- Bootstrap - Dropdowns
- Bootstrap - List Group
- Bootstrap - Modal
- Bootstrap - Navbars
- Bootstrap - Navs & tabs
- Bootstrap - Offcanvas
- Bootstrap - Pagination
- Bootstrap - Placeholders
- Bootstrap - Popovers
- Bootstrap - Progress
- Bootstrap - Scrollspy
- Bootstrap - Spinners
- Bootstrap - Toasts
- Bootstrap - Tooltips
- Bootstrap Forms
- Bootstrap - Forms
- Bootstrap - Form Control
- Bootstrap - Select
- Bootstrap - Checks & radios
- Bootstrap - Range
- Bootstrap - Input Groups
- Bootstrap - Floating Labels
- Bootstrap - Layout
- Bootstrap - Validation
- Bootstrap Helpers
- Bootstrap - Clearfix
- Bootstrap - Color & background
- Bootstrap - Colored Links
- Bootstrap - Focus Ring
- Bootstrap - Icon Link
- Bootstrap - Position
- Bootstrap - Ratio
- Bootstrap - Stacks
- Bootstrap - Stretched link
- Bootstrap - Text Truncation
- Bootstrap - Vertical Rule
- Bootstrap - Visually Hidden
- Bootstrap Utilities
- Bootstrap - Backgrounds
- Bootstrap - Borders
- Bootstrap - Colors
- Bootstrap - Display
- Bootstrap - Flex
- Bootstrap - Floats
- Bootstrap - Interactions
- Bootstrap - Link
- Bootstrap - Object Fit
- Bootstrap - Opacity
- Bootstrap - Overflow
- Bootstrap - Position
- Bootstrap - Shadows
- Bootstrap - Sizing
- Bootstrap - Spacing
- Bootstrap - Text
- Bootstrap - Vertical Align
- Bootstrap - Visibility
- Bootstrap Demos
- Bootstrap - Grid Demo
- Bootstrap - Buttons Demo
- Bootstrap - Navigation Demo
- Bootstrap - Blog Demo
- Bootstrap - Slider Demo
- Bootstrap - Carousel Demo
- Bootstrap - Headers Demo
- Bootstrap - Footers Demo
- Bootstrap - Heroes Demo
- Bootstrap - Featured Demo
- Bootstrap - Sidebars Demo
- Bootstrap - Dropdowns Demo
- Bootstrap - List groups Demo
- Bootstrap - Modals Demo
- Bootstrap - Badges Demo
- Bootstrap - Breadcrumbs Demo
- Bootstrap - Jumbotrons Demo
- Bootstrap-Sticky footer Demo
- Bootstrap-Album Demo
- Bootstrap-Sign In Demo
- Bootstrap-Pricing Demo
- Bootstrap-Checkout Demo
- Bootstrap-Product Demo
- Bootstrap-Cover Demo
- Bootstrap-Dashboard Demo
- Bootstrap-Sticky footer navbar Demo
- Bootstrap-Masonry Demo
- Bootstrap-Starter template Demo
- Bootstrap-Album RTL Demo
- Bootstrap-Checkout RTL Demo
- Bootstrap-Carousel RTL Demo
- Bootstrap-Blog RTL Demo
- Bootstrap-Dashboard RTL Demo
- Bootstrap Useful Resources
- Bootstrap - Questions and Answers
- Bootstrap - Quick Guide
- Bootstrap - Useful Resources
- Bootstrap - Discussion
Bootstrap - Scrollspy
This chapter will discuss about Bootstrap scrollspy. Bootstrap scrollspy automatically targets the navigation bar contents as you scroll the page.
How it work
When the element with the id referred by the anchor's href is scrolled into view, scrollspy works with nav, list group, and also works with any anchor element in the current page. Here's how it's works.
In order to utilize scrollspy, you should have two thing i.e a navigation, list group or a simple set of links, along with scrollable container such as the <body> or a custom element with a specific height and overflow-y: scroll.
To the scrollspy container, add attributes data-bs-spy="scroll" and data-bs-target="#navId", where "navId" refers the unique id of the corresponding navigation. If the container does not have any focusable element, include tabindex="0" to guarantee keyboard accessibility.
When you scroll within the "spied" container, anchor links in the navigation will have an .active class added or removed. If the id targets of links cannot be resolved, they will be ignored. For example, a <a href="#home">home</a> should have a corresponding <div id="home"></div>.
In the non-visible elements section, only visible elements will be considered and targeted.
Navbar
Scroll below the navbar area to see active class change. Open the dropdown and see highlighted items.
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <nav id="navbarFirstExample" class="navbar bg-body-tertiary px-3 mb-3"> <a class="navbar-brand" href="#">Tutorialspoints</a> <ul class="nav nav-pills"> <li class="nav-item"> <a class="nav-link" href="#scrollspyFirstTitle">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspySecondTitle">Services</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyThirdTitle">About us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFourthTitle">Contact us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFifthTitle">Features</a> </li> </ul> </nav> <div data-bs-spy="scroll" data-bs-target="#navbarFirstExample" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 rounded-2" tabindex="0"> <h4 id="scrollspyFirstTitle">Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="scrollspySecondTitle">Services</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyThirdTitle">About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFourthTitle">Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFifthTitle">Features</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> </body> </html>
Nested nav
Scrollspy supports nested .navs and makes their parents .active when they are .active. See active class changes while scrolling the navbar.
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="row mt-2"> <div class="col-4"> <nav id="nestatedNavbar" class="h-100 flex-column align-items-stretch pe-4 border-end"> <nav class="nav nav-pills flex-column"> <a class="nav-link" href="#home">Home</a> <nav class="nav nav-pills flex-column"> <a class="nav-link ms-3 my-1" href="#login">Log in</a> <a class="nav-link ms-3 my-1" href="#logout">Log out</a> </nav> <a class="nav-link" href="#aboutus">About us</a> <a class="nav-link" href="#contactus">Contact Us</a> </nav> </nav> </div> <div class="col-8"> <div data-bs-spy="scroll" data-bs-target="#nestatedNavbar" data-bs-smooth-scroll="true" class="bg-body-tertiary p-3 rounded-2 my-2" tabindex="0"> <div id="home"> <h4>Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> <div id="login"> <h5>Log In</h5> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group</p> </div> <div id="logout"> <h5>Log out</h5> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> <div id="aboutus"> <h4>About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group</p> </div> <div id="contactus"> <h4>Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> </div> </div> </div> </body> </html>
List group
Scrollspy supports .list-groups. See the active class change as you scroll near the list group.
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="row mt-2"> <div class="col-4"> <div id="navbarList" class="list-group my-2"> <a class="list-group-item list-group-item-action" href="#home">Home</a> <a class="list-group-item list-group-item-action" href="#services">Services</a> <a class="list-group-item list-group-item-action" href="#aboutus">About us</a> <a class="list-group-item list-group-item-action" href="#contactus">Contact us</a> <a class="list-group-item list-group-item-action" href="#features">Features</a> </div> </div> <div class="col-8"> <div data-bs-spy="scroll" data-bs-target="#navbarList" data-bs-smooth-scroll="true" class="bg-body-tertiary p-3 rounded-2 my-2" tabindex="0"> <h4 id="home">Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area.</p> <h4 id="services">Services</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="aboutus">About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area.</p> <h4 id="contactus">Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="features">Features</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. </p> </div> </div> </div> </div> </body> </html>
Simple anchors
Scrollspy works on all <a> anchor elements, not restricted to nav elements and list groups.
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="row"> <div class="col-4"> <div id="listUsingAnchor" class="text-center"> <nav class="nav nav-pills flex-column mx-3"> <a class="nav-link active" href="#home">Home</a> <a class="nav-link" href="#services">Services</a> <a class="nav-link" href="#aboutus">About us</a> <a class="nav-link" href="#contactus">Contact us</a> <a class="nav-link" href="#features">Features</a> </nav> </div> </div> <div class="col-8"> <div data-bs-spy="scroll" data-bs-target="#listUsingAnchor" data-bs-offset="0" data-bs-smooth-scroll="true" class="bg-body-tertiary p-3 rounded-2 my-2" tabindex="0"> <h4 id="home">Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="services">Services</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="aboutus">About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="contactus">Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="features">Features</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> </div> </div> </div> </body> </html>
Non-visible elements
Non-visible elements will be disregarded, and their corresponding nav items will not be assigned the .active class. Scrollspy instances that are initialized within an non-visible wrapper ignores all target elements. Use refresh method in case the wrapper becomes visible. This helps check for observable elements .
Example
document.querySelectorAll('#nav-tab>[data-bs-toggle="tab"]').forEach(el => { el.addEventListener('shown.bs.tab', () => { const target = el.getAttribute('data-bs-target') const scrollElem = document.querySelector(`${target} [data-bs-spy="scroll"]`) bootstrap.ScrollSpy.getOrCreateInstance(scrollElem).refresh() }) })
Usage
Via data attributes
Add data-bs-spy="scroll" to the element to spy on (usually the <body>) to quickly add scroll spy behavior to topbar navigation. Then, specifying the id or class name of the parent element of any Bootstrap .nav component using the "data-bs-target" attribute.
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body data-bs-spy="scroll" data-bs-target="#navbarDataAttribute"> <div id="navbarDataAttribute" class="my-2"> <ul class="nav nav-pills" role="pillslist"> <li class="nav-item"> <a class="nav-link" href="#scrollspyFirstTitle">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspySecondTitle">Services</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyThirdTitle">About us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFourthTitle">Contact us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFifthTitle">Features</a> </li> </ul> <div data-bs-spy="scroll" data-bs-target="#navbarDataAttribute" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="bg-body-tertiary p-3 rounded-2 my-2" tabindex="0"> <h4 id="scrollspyFirstTitle">Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="scrollspySecondTitle">Services</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyThirdTitle">About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFourthTitle">Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFifthTitle">Features</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> </div> </body> </html>
Via JavaScript
To enable scrollspy behavior on your topbar navigation, add data-bs-spy="scroll" to the desired element (usually the <body> tag).
Inside the <script> tag apply scroll spy to a component using the identifier or class like "navbarJavaScript".
Example
You can edit and try running this code using Edit & Run option.
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap - Scrollspy</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script> </head> <body data-bs-spy="scroll" data-bs-target="#navbarJavaScript"> <div id="navbarJavaScript"> <ul class="nav nav-pills" role="pillslist"> <li class="nav-item"> <a class="nav-link" href="#scrollspyFirstTitle">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspySecondTitle">Services</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyThirdTitle">About us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFourthTitle">Contact us</a> </li> <li class="nav-item"> <a class="nav-link" href="#scrollspyFifthTitle">Features</a> </li> </ul> <div data-bs-spy="scroll" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 rounded-2" tabindex="0"> <h4 id="scrollspyFirstTitle">Home</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspySecondTitle">Services</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyThirdTitle">About us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFourthTitle">Contact us</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group. Scrollspy works with nav and list group.</p> <h4 id="scrollspyFifthTitle">Features</h4> <p>Bootstrap Scrollspy targets the navigation bar contents automatically on scrolling the area. Scrollspy works with nav and list group.</p> </div> </div> <script> const scrollSpy = new bootstrap.ScrollSpy(document.body, { target: '#navbarJavaScript' }) </script> </body> </html>
Otpions
Options can be provided through data attributes or JavaScript
To add an option name to data-bs-, as in data-bs-animation={value}," use either data attributes or JavaScript. If using data attributes, use "kebab-case" instead of "camelCase" for the option name. For example, use data-bs-custom-class="beautifier" instead of data-bs-custom-class="beautifier".
Bootstrap 5.2.0 has added a new feature called data-bs-config attribute to store basic component configurations as a JSON string. If an element has both data-bs-config and separate data attributes, the separate data attributes' values take precedence over those in data-bs-config. Even, existing data attributes can also store JSON values.
Data-bs-config, data-bs-, and js objects are combined to create the final configuration object, where the most recent key-value overrides all others.
CSS Properties
The table describes the properties and their corresponding values for a ScrollSpy plugin.
Name | Type | Default | Description |
---|---|---|---|
rootMargin |
string | 0px 0px -25% |
Intersection Observer rootMargin valid units, when calculating scroll position. |
smoothScroll |
boolean | false |
Enables smooth scrolling when a user clicks on a link that refers to ScrollSpy observables. |
target |
string, DOM element | null |
Specifies element to apply Scrollspy plugin. |
threshold |
array | [0.1, 0.5, 1] |
IntersectionObserver threshold valid input, when calculating scroll position. |