Skip to main content
RapidDev - Software Development Agency
bubble-tutorial

How to create a reading progress indicator in Bubble.io: Step-by-Step Guide

Add a reading progress indicator to your Bubble app that shows a horizontal bar at the top of the page filling as the user scrolls through article content. This tutorial covers tracking scroll position with JavaScript, updating a custom state, and dynamically resizing a progress bar element so readers always know how far they have read.

What you'll learn

  • How to track scroll position using JavaScript in a Bubble HTML element
  • How to update a custom state based on scroll percentage
  • How to build a fixed progress bar at the top of the page
  • How to style the progress indicator with smooth transitions
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read10-15 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

Add a reading progress indicator to your Bubble app that shows a horizontal bar at the top of the page filling as the user scrolls through article content. This tutorial covers tracking scroll position with JavaScript, updating a custom state, and dynamically resizing a progress bar element so readers always know how far they have read.

Overview: Creating a Reading Progress Indicator in Bubble

This tutorial shows you how to add a scroll-based reading progress bar to your Bubble blog or article pages. The bar sits at the top of the page and fills from left to right as the reader scrolls down. You will use a small JavaScript snippet in an HTML element to detect scroll position, pass it to a Bubble custom state, and use that state to dynamically set the width of a colored bar element.

Prerequisites

  • A Bubble account with a page containing long-form content
  • Basic familiarity with Bubble's Design tab
  • Understanding of custom states in Bubble

Step-by-step guide

1

Create a fixed progress bar at the top of the page

On your article or blog post page, add a Floating Group element at the top of the page. Set it to float relative to Top and make it full width with a height of 4 pixels. Set the background to transparent or a light grey. Inside this Floating Group, add a Group element (the progress fill). Set this inner group's height to 100 percent, background to a bold color like blue (#3B82F6), and align it to the left. Set its width to 0 percent initially. Give this inner group an ID of progress-bar in the element's settings.

Pro tip: Keep the progress bar height between 3 and 5 pixels for a subtle effect that does not distract from the content.

Expected result: A thin bar appears fixed at the top of the page, initially with zero width.

2

Add a custom state to store the scroll percentage

Click on the page element itself (not any child element). In the Property Editor, go to the element's custom states and create a new state called Scroll Percent of type number with a default value of 0. This state will be updated by JavaScript as the user scrolls and will drive the progress bar width.

Expected result: A Scroll Percent custom state exists on the page element with a default value of 0.

3

Add JavaScript to track scroll position

Add an HTML element to the page (it can be placed anywhere since it will be invisible). Paste a script that listens for the scroll event on the window. The script calculates the scroll percentage as: (how far the user has scrolled) divided by (total scrollable height minus the viewport height), multiplied by 100. It then updates the progress bar width directly using the element ID. This approach avoids the overhead of constantly updating a custom state on every scroll pixel.

HTML element — scroll tracking script
1<script>
2window.addEventListener('scroll', function() {
3 var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
4 var docHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
5 var scrollPercent = (scrollTop / docHeight) * 100;
6 var bar = document.getElementById('progress-bar');
7 if (bar) {
8 bar.style.width = scrollPercent + '%';
9 }
10});
11</script>

Expected result: The progress bar width updates smoothly in real time as the user scrolls through the page content.

4

Add smooth transitions to the progress bar

Add another HTML element (or append to the existing one) with a style tag that targets the progress bar ID. Set a CSS transition on the width property so the bar animates smoothly rather than jumping between positions. A transition of 0.1 seconds with ease timing provides a responsive feel without lag.

HTML element — progress bar styling
1<style>
2#progress-bar {
3 transition: width 0.1s ease;
4}
5</style>

Expected result: The progress bar fills smoothly as the user scrolls, with no visual jumping between positions.

5

Test and adjust for different content lengths

Preview your page and scroll through the content. The bar should read 0 percent at the top and reach 100 percent when you scroll to the very bottom. If the bar reaches 100 percent too early, check that the HTML element is placed within the page content flow (not inside a group that limits its height). If the page has a fixed-height container, you may need to modify the script to track the container's scroll position instead of the window. Test on both desktop and mobile viewports.

Expected result: The progress bar accurately shows 0 percent at the top and 100 percent at the bottom of the content on all screen sizes.

Complete working example

HTML element — complete reading progress indicator
1<!-- READING PROGRESS INDICATOR -->
2<!-- Place this HTML element anywhere on the page -->
3
4<style>
5 #progress-bar {
6 transition: width 0.1s ease;
7 }
8</style>
9
10<script>
11 // Track scroll position and update progress bar
12 window.addEventListener('scroll', function() {
13 var scrollTop = window.pageYOffset
14 || document.documentElement.scrollTop;
15 var docHeight = document.documentElement.scrollHeight
16 - document.documentElement.clientHeight;
17
18 if (docHeight <= 0) return; // Prevent division by zero
19
20 var scrollPercent = Math.min(
21 (scrollTop / docHeight) * 100,
22 100
23 );
24
25 var bar = document.getElementById('progress-bar');
26 if (bar) {
27 bar.style.width = scrollPercent + '%';
28 }
29 });
30
31 // Reset on page load
32 window.addEventListener('load', function() {
33 var bar = document.getElementById('progress-bar');
34 if (bar) {
35 bar.style.width = '0%';
36 }
37 });
38</script>
39
40<!--
41 BUBBLE SETUP:
42 1. Floating Group: top, full width, height 4px
43 2. Inner Group: id='progress-bar', height 100%,
44 bg #3B82F6, width starts at 0%
45 3. Place this HTML element anywhere on the page
46-->

Common mistakes when creating a reading progress indicator in Bubble.io: Step-by-Step Guide

Why it's a problem: Placing the progress bar inside a scrolling container instead of a Floating Group

How to avoid: Always use a Floating Group fixed to the top of the page for the progress bar container

Why it's a problem: Setting the progress bar to a fixed width instead of percentage-based

How to avoid: Use the JavaScript scroll calculation to set the width as a percentage of the viewport width

Why it's a problem: Not handling the case where page content is shorter than the viewport

How to avoid: Add a guard clause checking that docHeight is greater than zero before calculating the percentage

Best practices

  • Keep the progress bar thin (3-5 pixels) so it does not distract from content
  • Use a Floating Group fixed to the top of the viewport for consistent positioning
  • Add a CSS transition for smooth animation instead of jumpy width changes
  • Include a guard clause for pages with content shorter than the viewport
  • Use a high-contrast color for the progress bar that matches your brand
  • Test on both desktop and mobile since scrolling behavior differs between devices

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I want to add a reading progress indicator to my Bubble.io blog pages. The bar should sit at the top of the page and fill as the user scrolls through the article. How do I set this up with JavaScript and Bubble elements?

Bubble Prompt

Add a thin progress bar at the top of my blog post page that fills from left to right as the reader scrolls through the article. Use a Floating Group and JavaScript to track scroll position.

Frequently asked questions

Can I change the color of the progress bar dynamically?

Yes. Modify the JavaScript to change the bar's background color based on the scroll percentage. For example, change from blue to green as the reader progresses past 50 percent.

Does this work on mobile browsers?

Yes. The scroll event fires on mobile browsers. However, some mobile browsers have address bar behavior that affects the total scrollable height. The Math.min guard in the script ensures the bar never exceeds 100 percent.

Will this affect my app's performance?

The scroll event fires very frequently. The script is lightweight (just a division and a style update), so the performance impact is minimal. Avoid adding database operations or complex calculations inside the scroll handler.

Can I show the percentage as a number alongside the bar?

Yes. Add a Text element inside the Floating Group. Modify the JavaScript to also update a Bubble custom state (using bubble_fn_scrollPercent for Toolbox plugin) so the Text element can display the number dynamically.

Can RapidDev help add advanced reading features?

Yes. RapidDev can help you build reading features like estimated read time, bookmarking positions, and progress saving so returning readers pick up where they left off.

How do I hide the progress bar on non-article pages?

Only add the Floating Group with the progress bar to article pages, or use a Reusable Element that you place only on pages where reading progress makes sense.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.