Scroll Progress Bar Override

Scroll Progress Bar Override

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

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    2 Types of Horizontal Scrolling in Framer

    2 Types of Horizontal Scrolling Effect in Framer

    Effect

    2 Types of Horizontal Scrolling in Framer

    2 Types of Horizontal Scrolling Effect in Framer

    Effect

    2 Types of Horizontal Scrolling in Framer

    2 Types of Horizontal Scrolling Effect in Framer

    Effect