1. Plugins
  2. Scrollspy

Plugins

Tailwind CSS Scrollspy

Automatically update navigation or list group components based on scroll position to indicate which link is currently active in the viewport.

Image Description

Installation

To get started with Scrollspy, install Overlay plugin via npm, else you can skip this step if you are already using Preline UI as a package.

                      
                        npm i @preline/scrollspy
                      
                    

Example

Scroll the area below the navbar and watch the active class change. The dropdown items will be highlighted as well.

First

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Second

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Third

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Fourth

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Fifth

This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.

Basic usage

Prefer to create your own style? Here is a completely unstylized example.

                      
                        <header class="sticky top-0 inset-x-0 flex flex-wrap sm:justify-start sm:flex-nowrap z-40 w-full">
                          <nav class="max-w-[85rem] w-full mx-auto sm:flex sm:items-center sm:justify-between" aria-label="Global">
                            <div class="flex items-center justify-between">
                              <a class="flex-none" href="#">Brand</a>
                              <div class="sm:hidden">
                                <button type="button" class="hs-collapse-toggle p-2 inline-flex justify-center items-center gap-2 align-middle" data-hs-collapse="#navbar-collapse-unstyled" aria-controls="navbar-collapse-unstyled" aria-label="Toggle navigation">
                                  <svg class="hs-collapse-open:hidden w-4 h-4" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
                                    <path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
                                  </svg>
                                  <svg class="hs-collapse-open:block hidden w-4 h-4" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
                                    <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
                                  </svg>
                                </button>
                              </div>
                            </div>
                            <div id="navbar-collapse-unstyled" class="hidden overflow-hidden transition-all duration-300 basis-full grow sm:block">
                              <div data-hs-scrollspy="#scrollspy-1" data-hs-scrollspy-scrollable-parent="#scrollspy-scrollable-parent-1" class="flex flex-col gap-5 mt-5 sm:flex-row sm:items-center sm:justify-end sm:mt-0 sm:pl-5 [--scrollspy-offset:70]">
                                <a class="active" href="#first">First</a>
                                <a href="#second">Second</a>

                                <div data-hs-scrollspy-group class="hs-dropdown [--placement:bottom-right]">
                                  <a id="hs-mega-menu-basic-dr" type="button" class="group hs-scrollspy-active:text-blue-600 mb-3 sm:mb-0 dark:hs-scrollspy-active:text-blue-400 inline-flex justify-center items-center gap-2 text-sm text-gray-700 leading-6 hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-500 hs-scrollspy-active:text-blue-600 dark:hs-scrollspy-active:text-blue-400" href='javascript:;'>
                                    Dropdown
                                    <svg class="ml-2 w-2.5 h-2.5 text-gray-600" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                                      <path d="M2 5L8.16086 10.6869C8.35239 10.8637 8.64761 10.8637 8.83914 10.6869L15 5" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
                                    </svg>
                                  </a>

                                  <div class="hs-dropdown-menu transition-[opacity,margin] duration-[0.1ms] sm:duration-[150ms] hs-dropdown-open:opacity-100 opacity-0 sm:w-48 z-10 bg-white sm:shadow-md rounded-lg p-2 dark:bg-gray-800 sm:dark:border dark:border-gray-700 dark:divide-gray-700 before:absolute top-full sm:border before:-top-5 before:left-0 before:w-full before:h-5 hidden" style="">
                                    <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-700 leading-6 hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-500 hs-scrollspy-active:text-blue-600 dark:hs-scrollspy-active:text-blue-400" href="#third">
                                      Third
                                    </a>
                                    <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-700 leading-6 hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-500 hs-scrollspy-active:text-blue-600 dark:hs-scrollspy-active:text-blue-400" href="#fourth">
                                      Fourth
                                    </a>
                                    <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-700 leading-6 hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-500 hs-scrollspy-active:text-blue-600 dark:hs-scrollspy-active:text-blue-400" href="#fifth">
                                      Fifth
                                    </a>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </nav>
                        </header>

                        <div id="scrollspy-1" class="mt-3 space-y-4">
                          <div id="first">
                            <h3>First</h3>
                            <p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
                          </div>

                          <div id="second">
                            <h3>Second</h3>
                            <p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
                          </div>

                          <div id="third">
                            <h3>Third</h3>
                            <p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
                          </div>

                          <div id="fourth">
                            <h3>Fourth</h3>
                            <p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
                          </div>

                          <div id="fifth">
                            <h3>Fifth</h3>
                            <p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
                          </div>
                        </div>
                      
                    

Options

Parameters Description Options Default value
data-hs-scrollspy Container selector containing sections Selector
[--scrollspy-offset:*] Adds offset when scrolling to the section and to determine if the section is active Number 0
data-hs-scrollspy-scrollable-parent Specifies the element to be scrolled Selector window

Classes

Name Description
hs-scrollspy-active A modifier that allows you to set taiwind classes when the section is active for link

Demo examples

Looking for prebuilt UI components based on the Tailwind CSS? Preline UI packs hundreds of component examples for all your website needs.

Image Description
Check out Preline UI Scrollspy