Skip to content

📜  Scroll to Element

Submitted by Lukas Masuch

Summary

Programmatically scroll to any element by its key.

Functions

scroll_to_element

Scroll the page to an element with the specified key.

This component scrolls the browser viewport to make a specific element visible. The target element must have been created with a key parameter (e.g., st.text_input("Label", key="my_key")).

Parameters:

Name Type Description Default
key str

The key of the target element to scroll to. The element must have been created with a key parameter.

required
scroll_mode Literal['smooth', 'instant', 'auto']

The scroll behavior. "smooth" animates the scroll, "instant" jumps immediately, "auto" uses browser preference. Default is "smooth".

'smooth'
alignment Literal['start', 'center', 'end', 'nearest']

Where to position the element in the viewport after scrolling. "start" aligns to the top, "center" centers it, "end" aligns to the bottom, "nearest" scrolls the minimum distance. Default is "center".

'center'

Example:

```python
st.text_input("Name", key="name_field")
if st.button("Jump to name field"):
    scroll_to_element("name_field")
```
Note
  • The target element must have a key parameter set in its Streamlit call
  • If no element with the specified key exists, the scroll is silently ignored
  • Use conditionally (e.g., in button callbacks) to avoid scrolling on every rerun
Source code in src/streamlit_extras/scroll_to_element/__init__.py
@extra
def scroll_to_element(
    key: str,
    *,
    scroll_mode: Literal["smooth", "instant", "auto"] = "smooth",
    alignment: Literal["start", "center", "end", "nearest"] = "center",
) -> None:
    """Scroll the page to an element with the specified key.

    This component scrolls the browser viewport to make a specific element
    visible. The target element must have been created with a `key` parameter
    (e.g., `st.text_input("Label", key="my_key")`).

    Args:
        key: The key of the target element to scroll to. The element must have
            been created with a `key` parameter.
        scroll_mode: The scroll behavior. "smooth" animates the scroll, "instant"
            jumps immediately, "auto" uses browser preference. Default is "smooth".
        alignment: Where to position the element in the viewport after scrolling.
            "start" aligns to the top, "center" centers it, "end" aligns to the
            bottom, "nearest" scrolls the minimum distance. Default is "center".

    Example:

        ```python
        st.text_input("Name", key="name_field")
        if st.button("Jump to name field"):
            scroll_to_element("name_field")
        ```

    Note:
        - The target element must have a `key` parameter set in its Streamlit call
        - If no element with the specified key exists, the scroll is silently ignored
        - Use conditionally (e.g., in button callbacks) to avoid scrolling on every rerun
    """
    if not key or not key.strip():
        return

    class_name = _key_to_class_name(key)

    # Use st._event container to avoid adding any visual space to the UI
    with st._event:
        _SCROLL_COMPONENT(
            data={
                "class_name": class_name,
                "scroll_mode": scroll_mode,
                "alignment": alignment,
                "request_id": 1,
            },
            width="stretch",
            height=0,
        )

Import:

from streamlit_extras.scroll_to_element import scroll_to_element # (1)!
  1. You should add this to the top of your .py file 🛠

Examples

example_basic

def example_basic() -> None:
    """Example: Basic scroll navigation."""
    st.write("Click the buttons to scroll to different sections of the page.")

    # Navigation buttons at the top
    col1, col2, col3, col4 = st.columns(4)
    with col1:
        if st.button("Go to Introduction", key="nav_intro"):
            scroll_to_element("intro_section")
    with col2:
        if st.button("Go to Name Input", key="nav_name"):
            scroll_to_element("name_input")
    with col3:
        if st.button("Go to Middle Section", key="nav_middle"):
            scroll_to_element("middle_section")
    with col4:
        if st.button("Go to Conclusion", key="nav_conclusion"):
            scroll_to_element("conclusion_section")

    # Create sections with keys using containers
    with st.container(key="intro_section"):
        st.header("Introduction")
        st.write(
            "This example demonstrates how to scroll to elements by their key. "
            "Click the buttons above to navigate between sections."
        )

    # Add some spacer content
    for i in range(10):
        st.write(f"Content block {i + 1}")

    with st.container(key="middle_section"):
        st.header("Middle Section")
        st.text_input("Enter your name", key="name_input")
        st.write("This is the middle of the page with a text input.")

    for i in range(10):
        st.write(f"More content {i + 1}")

    with st.container(key="conclusion_section"):
        st.header("Conclusion")
        st.write("You've reached the end of the page!")

example_smooth_vs_instant

def example_smooth_vs_instant() -> None:
    """Example: Compare smooth and instant scrolling."""
    st.write("Compare different scroll behaviors.")

    with st.container(key="scroll_target"):
        st.header("Target Element")
        st.info("This is the target element for scrolling.")

    for i in range(15):
        st.write(f"Spacer content line {i + 1}")

    st.subheader("Scroll Options")
    col1, col2, col3 = st.columns(3)

    with col1:
        if st.button("Smooth scroll", key="smooth_btn"):
            scroll_to_element("scroll_target", scroll_mode="smooth")

    with col2:
        if st.button("Instant scroll", key="instant_btn"):
            scroll_to_element("scroll_target", scroll_mode="instant")

    with col3:
        if st.button("Align to top", key="center_btn"):
            scroll_to_element("scroll_target", alignment="start")