Skip to content

Scrollspy

Automatically update navigation based on scroll position.

Basic Usage

from faststrap import Scrollspy

# In your navigation
Nav(
    A("Section 1", href="#section1"),
    A("Section 2", href="#section2"),
    A("Section 3", href="#section3"),
    id="navbar"
)

# Scrollspy container
Scrollspy(
    Div(H2("Section 1", id="section1"), P("Content...")),
    Div(H2("Section 2", id="section2"), P("Content...")),
    Div(H2("Section 3", id="section3"), P("Content...")),
    target="#navbar"
)

API Reference

Parameter Type Default Description
*children Any - Scrollable content
target str Required Selector for navigation element
offset int 10 Offset from top (px)
method str "auto" Scroll method: "auto" or "position"
**kwargs Any - Additional HTML attributes

Examples

Documentation Sidebar

# Sidebar navigation
Div(
    Nav(
        A("Introduction", href="#intro", cls="nav-link"),
        A("Installation", href="#install", cls="nav-link"),
        A("Usage", href="#usage", cls="nav-link"),
        id="docNav",
        cls="flex-column"
    ),
    cls="col-md-3"
)

# Main content with scrollspy
Div(
    Scrollspy(
        Section(H2("Introduction", id="intro"), P("...")),
        Section(H2("Installation", id="install"), P("...")),
        Section(H2("Usage", id="usage"), P("...")),
        target="#docNav"
    ),
    cls="col-md-9"
)

Table of Contents

# TOC
Nav(
    A("Overview", href="#overview"),
    A("Features", href="#features"),
    A("Pricing", href="#pricing"),
    id="toc"
)

# Content
Scrollspy(
    Div(H2("Overview", id="overview"), P("...")),
    Div(H2("Features", id="features"), P("...")),
    Div(H2("Pricing", id="pricing"), P("...")),
    target="#toc",
    offset=100
)

Accessibility

  • Maintains keyboard navigation
  • Updates ARIA attributes automatically
  • Works with screen readers

See Also

  • Navbar - Navigation component
  • Tabs - Tabbed navigation

Generated API Reference

faststrap.components.navigation.scrollspy.Scrollspy(*children, target, offset=None, method=None, smooth_scroll=None, **kwargs)

Bootstrap Scrollspy for auto-updating navigation based on scroll position.

Automatically updates navigation links based on scroll position. Highlights the current section in the navigation as you scroll through the page.

Parameters:

Name Type Description Default
*children Any

Content sections to watch

()
target str

CSS selector for the navigation element (e.g., "#navbar")

required
offset int | None

Offset from top in pixels when calculating position

None
method str | None

Scrollspy method ("auto", "offset", or "position")

None
smooth_scroll bool | None

Enable smooth scrolling when clicking nav links

None
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Div

FastHTML Div element with scrollspy data attributes

Examples:

Basic scrollspy:

>>> # Navigation
>>> Navbar(
...     NavItem("Section 1", href="#section1"),
...     NavItem("Section 2", href="#section2"),
...     id="navbar"
... )
>>>
>>> # Content with scrollspy
>>> Scrollspy(
...     Div(H2("Section 1"), P("Content..."), id="section1"),
...     Div(H2("Section 2"), P("Content..."), id="section2"),
...     target="#navbar"
... )

With offset:

>>> Scrollspy(
...     Div(..., id="intro"),
...     Div(..., id="features"),
...     target="#nav",
...     offset=100  # Account for fixed navbar
... )
Note

Requires Bootstrap's JavaScript. Navigation items must have href attributes matching the IDs of the content sections.

See Also

Bootstrap docs: https://getbootstrap.com/docs/5.3/components/scrollspy/

Source code in src/faststrap/components/navigation/scrollspy.py
@register(category="navigation", requires_js=True)
def Scrollspy(
    *children: Any,
    target: str,
    offset: int | None = None,
    method: str | None = None,
    smooth_scroll: bool | None = None,
    **kwargs: Any,
) -> Div:
    """Bootstrap Scrollspy for auto-updating navigation based on scroll position.

    Automatically updates navigation links based on scroll position. Highlights
    the current section in the navigation as you scroll through the page.

    Args:
        *children: Content sections to watch
        target: CSS selector for the navigation element (e.g., "#navbar")
        offset: Offset from top in pixels when calculating position
        method: Scrollspy method ("auto", "offset", or "position")
        smooth_scroll: Enable smooth scrolling when clicking nav links
        **kwargs: Additional HTML attributes

    Returns:
        FastHTML Div element with scrollspy data attributes

    Examples:
        Basic scrollspy:
        >>> # Navigation
        >>> Navbar(
        ...     NavItem("Section 1", href="#section1"),
        ...     NavItem("Section 2", href="#section2"),
        ...     id="navbar"
        ... )
        >>>
        >>> # Content with scrollspy
        >>> Scrollspy(
        ...     Div(H2("Section 1"), P("Content..."), id="section1"),
        ...     Div(H2("Section 2"), P("Content..."), id="section2"),
        ...     target="#navbar"
        ... )

        With offset:
        >>> Scrollspy(
        ...     Div(..., id="intro"),
        ...     Div(..., id="features"),
        ...     target="#nav",
        ...     offset=100  # Account for fixed navbar
        ... )

    Note:
        Requires Bootstrap's JavaScript. Navigation items must have href
        attributes matching the IDs of the content sections.

    See Also:
        Bootstrap docs: https://getbootstrap.com/docs/5.3/components/scrollspy/
    """
    # Build data attributes
    data_attrs: dict[str, Any] = {
        "data_bs_spy": "scroll",
        "data_bs_target": target,
    }

    if offset is not None:
        data_attrs["data_bs_offset"] = str(offset)

    if method:
        data_attrs["data_bs_method"] = method

    if smooth_scroll:
        data_attrs["data_bs_smooth_scroll"] = "true"

    # Build classes
    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes("", user_cls)

    # Build attributes
    attrs: dict[str, Any] = {
        "cls": all_classes,
        "tabindex": "0",  # Required for scrollspy
    }
    attrs.update(data_attrs)
    attrs.update(convert_attrs(kwargs))

    return Div(*children, **attrs)