Scroll Progress Bar Override

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Effect

Scroll Progress Bar Override

This is a demo website showing you how to create a scroll progress bar in Framer that reflects your position on the page. Feel free to remix the file, copy the progress bar into your own site, and follow the set-up instructions listed below.

You can click this link to get the starter file I used in the tutorial video, so you can follow along.

image of Nandi Muzsik

Created by

Scroll Progress Bar Override
Scroll Progress Bar Override
Scroll Progress Bar Override
scroll progress bar thumbnail

Related Lesson

Framer Tutorial: Creating Scroll Progress Bars

scroll progress bar thumbnail

Related Lesson

Framer Tutorial: Creating Scroll Progress Bars

scroll progress bar thumbnail

Related Lesson

Framer Tutorial: Creating Scroll Progress Bars

About the resource

First, there's the progress bar itself, which we'll position at the top of the website with fixed positioning.

Next, there's a frame nested within the progress bar, known as the "line". We're going to animate this "line" from 0% width to 100% width as you scroll down the site with a code override applied to the frame.

Finally, there's an additional "head" frame within the 'line' frame. This acts like a glow at the end of the scroll bar line. We'll position this absolutely and pin it to the right side of the "line".

The code override works by transforming the 'line' frame's width from 0% to 100% between the "start" and "end" scroll sections on your site.

So, you'll need to add a scroll section called "start" where you want the progress bar animation to kick off, and a scroll section called "end" where the scroll bar should reach the right edge of the page.

Just copy and paste the code override from below into your file.

Watch the full video tutorial for more guidance.

Code override for the scroll progress bar line

Copy this code and paste it into a new override in your Framer project. Next, apply it to the 'line' frame that's within the progress bar.

About the resource

First, there's the progress bar itself, which we'll position at the top of the website with fixed positioning.

Next, there's a frame nested within the progress bar, known as the "line". We're going to animate this "line" from 0% width to 100% width as you scroll down the site with a code override applied to the frame.

Finally, there's an additional "head" frame within the 'line' frame. This acts like a glow at the end of the scroll bar line. We'll position this absolutely and pin it to the right side of the "line".

The code override works by transforming the 'line' frame's width from 0% to 100% between the "start" and "end" scroll sections on your site.

So, you'll need to add a scroll section called "start" where you want the progress bar animation to kick off, and a scroll section called "end" where the scroll bar should reach the right edge of the page.

Just copy and paste the code override from below into your file.

Watch the full video tutorial for more guidance.

Code override for the scroll progress bar line

Copy this code and paste it into a new override in your Framer project. Next, apply it to the 'line' frame that's within the progress bar.

About the resource

First, there's the progress bar itself, which we'll position at the top of the website with fixed positioning.

Next, there's a frame nested within the progress bar, known as the "line". We're going to animate this "line" from 0% width to 100% width as you scroll down the site with a code override applied to the frame.

Finally, there's an additional "head" frame within the 'line' frame. This acts like a glow at the end of the scroll bar line. We'll position this absolutely and pin it to the right side of the "line".

The code override works by transforming the 'line' frame's width from 0% to 100% between the "start" and "end" scroll sections on your site.

So, you'll need to add a scroll section called "start" where you want the progress bar animation to kick off, and a scroll section called "end" where the scroll bar should reach the right edge of the page.

Just copy and paste the code override from below into your file.

Watch the full video tutorial for more guidance.

Code override for the scroll progress bar line

Copy this code and paste it into a new override in your Framer project. Next, apply it to the 'line' frame that's within the progress bar.

import type { ComponentType } from "react"
import { useState, useEffect, useRef } from "react"

export function withProgress(Component): ComponentType {
    return (props) => {
        const [progress, setProgress] = useState(0)
        const [isScrolling, setIsScrolling] = useState(false)
        const prevScrollY = useRef(0)

        useEffect(() => {
            const calculateProgress = () => {
                const startEl = document.getElementById("start")
                const endEl = document.getElementById("end")
                if (startEl && endEl) {
                    const sectionHeight = endEl.offsetTop - startEl.offsetTop
                    const scrollDistance =
                        window.pageYOffset || document.documentElement.scrollTop
                    const sectionScrollDistance =
                        scrollDistance - startEl.offsetTop
                    const sectionProgress =
                        (sectionScrollDistance / sectionHeight) * 100
                    setProgress(sectionProgress)
                }
            }

            const handleScroll = () => {
                const scrollY =
                    window.pageYOffset || document.documentElement.scrollTop
                if (scrollY !== prevScrollY.current) {
                    prevScrollY.current = scrollY
                    calculateProgress()
                    setIsScrolling(true)
                }
            }

            const handleScrollEnd = () => {
                setIsScrolling(false)
            }

            calculateProgress()

            window.addEventListener("scroll", handleScroll)
            window.addEventListener("scrollend", handleScrollEnd)

            return () => {
                window.removeEventListener("scroll", handleScroll)
                window.removeEventListener("scrollend", handleScrollEnd)
            }
        }, [])

        return (
            <Component
                {...props}
                style={{
                    width: `${progress}%`,
                    transition: isScrolling ? "none" : "width 0.5s ease-in-out",
                }}
            />
        )
    }
}
import type { ComponentType } from "react"
import { useState, useEffect, useRef } from "react"

export function withProgress(Component): ComponentType {
    return (props) => {
        const [progress, setProgress] = useState(0)
        const [isScrolling, setIsScrolling] = useState(false)
        const prevScrollY = useRef(0)

        useEffect(() => {
            const calculateProgress = () => {
                const startEl = document.getElementById("start")
                const endEl = document.getElementById("end")
                if (startEl && endEl) {
                    const sectionHeight = endEl.offsetTop - startEl.offsetTop
                    const scrollDistance =
                        window.pageYOffset || document.documentElement.scrollTop
                    const sectionScrollDistance =
                        scrollDistance - startEl.offsetTop
                    const sectionProgress =
                        (sectionScrollDistance / sectionHeight) * 100
                    setProgress(sectionProgress)
                }
            }

            const handleScroll = () => {
                const scrollY =
                    window.pageYOffset || document.documentElement.scrollTop
                if (scrollY !== prevScrollY.current) {
                    prevScrollY.current = scrollY
                    calculateProgress()
                    setIsScrolling(true)
                }
            }

            const handleScrollEnd = () => {
                setIsScrolling(false)
            }

            calculateProgress()

            window.addEventListener("scroll", handleScroll)
            window.addEventListener("scrollend", handleScrollEnd)

            return () => {
                window.removeEventListener("scroll", handleScroll)
                window.removeEventListener("scrollend", handleScrollEnd)
            }
        }, [])

        return (
            <Component
                {...props}
                style={{
                    width: `${progress}%`,
                    transition: isScrolling ? "none" : "width 0.5s ease-in-out",
                }}
            />
        )
    }
}
import type { ComponentType } from "react"
import { useState, useEffect, useRef } from "react"

export function withProgress(Component): ComponentType {
    return (props) => {
        const [progress, setProgress] = useState(0)
        const [isScrolling, setIsScrolling] = useState(false)
        const prevScrollY = useRef(0)

        useEffect(() => {
            const calculateProgress = () => {
                const startEl = document.getElementById("start")
                const endEl = document.getElementById("end")
                if (startEl && endEl) {
                    const sectionHeight = endEl.offsetTop - startEl.offsetTop
                    const scrollDistance =
                        window.pageYOffset || document.documentElement.scrollTop
                    const sectionScrollDistance =
                        scrollDistance - startEl.offsetTop
                    const sectionProgress =
                        (sectionScrollDistance / sectionHeight) * 100
                    setProgress(sectionProgress)
                }
            }

            const handleScroll = () => {
                const scrollY =
                    window.pageYOffset || document.documentElement.scrollTop
                if (scrollY !== prevScrollY.current) {
                    prevScrollY.current = scrollY
                    calculateProgress()
                    setIsScrolling(true)
                }
            }

            const handleScrollEnd = () => {
                setIsScrolling(false)
            }

            calculateProgress()

            window.addEventListener("scroll", handleScroll)
            window.addEventListener("scrollend", handleScrollEnd)

            return () => {
                window.removeEventListener("scroll", handleScroll)
                window.removeEventListener("scrollend", handleScrollEnd)
            }
        }, [])

        return (
            <Component
                {...props}
                style={{
                    width: `${progress}%`,
                    transition: isScrolling ? "none" : "width 0.5s ease-in-out",
                }}
            />
        )
    }
}

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

More resources

More resources

  • Graphic showcasing the 'Cursor Trail' component in Framer with a dynamic cursor leaving a trail effect on a starry space background

    Cursor Trail Effect for Framer

    Effect

    Graphic showcasing the 'Cursor Trail' component in Framer with a dynamic cursor leaving a trail effect on a starry space background

    Cursor Trail Effect for Framer

    Effect

    Graphic showcasing the 'Cursor Trail' component in Framer with a dynamic cursor leaving a trail effect on a starry space background

    Cursor Trail Effect for Framer

    Effect

  • Scramble and appear text effect on a dark background with letters floating and options to copy component or remix

    Text Scramble Appear Effect in Framer

    Effect

    Scramble and appear text effect on a dark background with letters floating and options to copy component or remix

    Text Scramble Appear Effect in Framer

    Effect

    Scramble and appear text effect on a dark background with letters floating and options to copy component or remix

    Text Scramble Appear Effect in Framer

    Effect