Documentation

Documentation - Scrollspy.

Discover Marssel: an intelligent, minimal configuration CSS framework designed for fast interfaces and a simplified developer experience.

Scrollspy

Marssel offers a scrollspy system to track scroll position and automatically highlight navigation links corresponding to the visible section. Ideal for table of contents menus or page navigation.

Basic setup

The ScrollspyManager is automatically initialized:

const marssel = new Marssel();
// The ScrollspyManager is ready to use

HTML structure

A scrollspy consists of navigation and target sections:

Preview

Section 1

Content of section 1: Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iste laboriosam tempore facilis quod illo asperiores voluptatem nisi voluptate vel corrupti voluptatibus quam excepturi consequatur ullam ipsam veritatis, in dolorum ab.

Section 2

Content of section 2: Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iste laboriosam tempore facilis quod illo asperiores voluptatem nisi voluptate vel corrupti voluptatibus quam excepturi consequatur ullam ipsam veritatis, in dolorum ab.

Section 3

Content of section 3: Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iste laboriosam tempore facilis quod illo asperiores voluptatem nisi voluptate vel corrupti voluptatibus quam excepturi consequatur ullam ipsam veritatis, in dolorum ab.

<!-- Browsing with scrollspy -->
<nav data-scrollspy="content-container"
    data-scrollspy-active="bg-[red]"
>
    <a href="#section-1">Section 1</a>
    <a href="#section-2">Section 2</a>
    <a href="#section-3">Section 3</a>
</nav>

<!-- Section container -->
<div id="content-container">
    <section id="section-1">
        <h4>Section 1</h4>
        <p>Contents of section 1...</p>
    </section>

    <section id="section-2">
        <h4>Section 2</h4>
        <p>Contents of section 2...</p>
    </section>

    <section id="section-3">
        <h4>Section 3</h4>
        <p>Contents of section 3...</p>
    </section>
</div>

Options available

Customize the behavior with data attributes:

<nav data-scrollspy="content"
    data-scrollspy-offset="100"          <!-- Offset in pixels (default: 0) -->
    data-scrollspy-active="active"       <!-- Active class (default: active) -->
    data-scrollspy-threshold="0.2"       <!-- Visibility threshold (default: 0.2) -->
    data-scrollspy-smooth="true">        <!-- Smooth scrolling (default: true) -->
    <a href="#intro">Introduction</a>
    <a href="#features">Features</a>
    <a href="#pricing">Prices</a>
</nav>

Fixed side navigation

Example of a fixed table of contents:

Preview

Introduction

Content of the introduction...

<!-- Fixed navigation -->
<nav data-scrollspy="article-content"
    data-scrollspy-offset="80"
    class="qw-[200px] bg-[ffffff] p-[20px] rounded-[8px] shadow-[0_2px_8px_rgba(0_0_0_0.1)]"
>
    <h4 class="m-[0_0_16px_0] font-size-[14px] font-weight-[600] c-[6b7280] text-transform-[uppercase]">
        Table of contents
    </h4>
    <div class="d-[flex] flex-direction-[column] gap-[8px]">
        <a href="#introduction"
        class="link-scrollspy---[c-[6b7280]+text-dec-[none]+font-size-[14px]+p-[6px_0]+border-l-[2px_solid_transparent]+pl-[12px]+transition-[all_0.2s]] link-scrollspy---[c-[2563eb]]:hover">
            Introduction
        </a>
        <a href="#getting-started"
        class="link-scrollspy">
            Startup
        </a>
        <a href="#features"
        class="link-scrollspy">
            Features
        </a>
        <a href="#examples"
        class="link-scrollspy">
            Examples
        </a>
    </div>
</nav>

<!-- Style for active state -->
<style>
[data-scrollspy] a.active {
    color: #2563eb !important;
    border-left-color: #2563eb !important;
    font-weight: 600;
}
</style>

<!-- Article content -->
<div id="article-content" class="ml-[260px]">
    <section id="introduction">
        <h2>Introduction</h2>
        <p>Content of the introduction...</p>
    </section>
    <!-- Autres sections... -->
</div>

Horizontal navigation

Example of a navigation bar at the top of the page:

<header class="pos-[sticky] top-[0] bg-[ffffff] shadow-[0_2px_4px_rgba(0_0_0_0.1)] z-[100]">
    <nav data-scrollspy="page-content"
        data-scrollspy-offset="100"
        data-scrollspy-active="bg-[red]"
        class="d-[flex] justify-[center] gap-[32px] p-[16px]"
    >
        <a href="#home"
        class="link-scrollspy-hor---[c-[333]+text-dec-[none]+font-weight-[500]+transition-[color_0.2s]] link-scrollspy-hor---[c-[2563eb]]:hover">
            Welcome
        </a>
        <a href="#about"
        class="link-scrollspy-hor">
            About
        </a>
        <a href="#services"
        class="link-scrollspy-hor">
            Services
        </a>
        <a href="#contact"
        class="link-scrollspy-hor">
            Contact
        </a>
    </nav>
</header>

JavaScript API

Control scrollspy programmatically:

// Refresh all scrollspies (after DOM modification)
marssel.scrollspyManager.refreshAll();

// Refresh a specific scrollspy
const navElement = document.querySelector('[data-scrollspy]');
const scrollspy = marssel.scrollspyManager.scrollspies.get(navElement);
marssel.scrollspyManager.refreshScrollspy(scrollspy);

// Update all scrollspies
marssel.scrollspyManager.updateAll();

// Destroy a scrollspy
marssel.scrollspyManager.destroy(navElement);

// Destroy all scrollspies
marssel.scrollspyManager.destroyAll();

Automatic smooth scrolling

Scrollspy automatically activates smooth scrolling when clicking on links:

<!-- Smooth scrolling enabled by default -->
<nav data-scrollspy="content" data-scrollspy-smooth="true">
    <a href="#section-1">Section 1</a>
    <a href="#section-2">Section 2</a>
</nav>

<!-- Disable smooth scrolling -->
<nav data-scrollspy="content" data-scrollspy-smooth="false">
    <a href="#section-1">Section 1</a>
    <a href="#section-2">Section 2</a>
</nav>

Lag management

Use data-scrollspy-offset to compensate for fixed headers:

<!-- With fixed header of 80px -->
<nav data-scrollspy="content" data-scrollspy-offset="80">
    <a href="#section-1">Section 1</a>
    <a href="#section-2">Section 2</a>
</nav>

Visibility threshold

Control when a section is considered active:

<!-- Section active when 20% visible (default) -->
<nav data-scrollspy="content" data-scrollspy-threshold="0.2">
    <a href="#section-1">Section 1</a>
</nav>

<!-- Section active when 50% visible -->
<nav data-scrollspy="content" data-scrollspy-threshold="0.5">
    <a href="#section-1">Section 1</a>
</nav>