Needed an easy solution for a discrete progress bar that would compete 100% at the end of the content, not at the end of the page. Most progress bars complete when you’ve hit the end of the page. I wanted to complete at the end of the content, so it needed a little love.
Here’s the ZIP file with the HTML, CSS, and the JS. Most of the heavy lifting is in the JavaScript file, but there’s also some important behavior in the CSS.
The JavaScript
The script tracks down the appropriate elements. Then it grabs styles associated with the header
, main
, and footer
elements. We add a quick event listener to watch for when the user scrolls, and when they do, we fire the updateProgressBar()
function.
// Get the important elements const progressBar = document.getElementById('progressbar'); const mainElement = document.querySelector('main'); const headerElement = document.querySelector('header'); const footerElement = document.querySelector('footer'); // Get header height, main bottom margin, and set initial progress bar width const { height: headerHeight } = getComputedStyle(headerElement); const { marginBottom } = getComputedStyle(mainElement); const progressBarMinWidth = 2; progressBar.style.width = `${progressBarMinWidth}%`; // Listen for the scroll event on the window window.addEventListener('scroll', updateProgressBar); function updateProgressBar() { // Calculate the scroll percentage const maxScrollHeight = document.documentElement.scrollHeight - window.innerHeight - footerElement.offsetHeight - parseFloat(marginBottom); const scrollPercentage = Math.min((window.scrollY / maxScrollHeight) * 100, 100); // Set the width of the progress bar based on the scroll percentage progressBar.style.width = `${Math.max(progressBarMinWidth, scrollPercentage)}%`; // Check if the user has scrolled past the header progressBar.classList.toggle('fixed', window.scrollY >= parseFloat(headerHeight)); // Check if the progress bar is 100% progressBar.classList.toggle('complete', window.scrollY >= maxScrollHeight ); }
Progress Bar Initialized
The progress bar starts off at the bottom of the footer.
User Scrolls Past Header
Then, as the user scrolls past the header, the progress bar pins to the top and expands as the user scrolls through the content.
User Finishes Content
Note that the vertical scroll bar has some more to go (for the footer that I made inordinately large for this demo). Even though there’s more vertical scroll, the progress meter is registering complete. I added a little checkmark embellishment to further visually conform that the content is complete.
Scrolling Past End of Meaningful Content
The user can continue scrolling to reach the bottom of the page itself.
Leave a Reply