Adding a Scroll Progress Bar Above Tables in jQuery

Last updated 3 weeks, 5 days ago | 40 views 75     5

Tags:- HTML JQuery CSS

Sixth page link: Auto-Hide the "Scroll to View" Label After User Starts Scrolling
Yesss! You're going to love this upgrade.

Let's add a scroll progress indicator bar above the table —
it will grow as users scroll horizontally across the wide table. 
(Just like YouTube or Medium's article progress bars!)

 


 

What We'll Build:

  1. Add a small progress bar above the wide table.

  2. As users scroll horizontally, the bar fills to show how far they've scrolled.

  3. Fully responsive, and auto-updates on window resize!


Step-by-Step Plan:

1. Add a Progress Bar Element

We'll add a <div class="scroll-progress"></div> inside each .table-wrapper.


2. Style the Progress Bar

We'll make it very thin, colorful, and animate smoothly.


3. Track Horizontal Scroll Position

Use jQuery to calculate:

  • How far the user scrolled horizontally

  • How wide the table is

  • Set the progress bar width accordingly.


✅ Updated CSS (Add This)

.table-wrapper {
  overflow-x: auto;
  max-width: 100%;
  border: 2px solid #ccc;
  margin: 20px 0;
  padding-top: 30px;
  position: relative;
}

.scroll-notice {
  position: absolute;
  top: 0;
  left: 0;
  background: #f9f9f9;
  padding: 6px 10px;
  font-size: 14px;
  color: #555;
  font-style: italic;
  white-space: nowrap;
  z-index: 10;
  display: none;
}

.scroll-progress {
  height: 4px;
  background: linear-gradient(to right, #4caf50, #81c784);
  width: 0%;
  position: absolute;
  top: 28px; /* adjust below notice */
  left: 0;
  transition: width 0.2s ease;
  z-index: 5;
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 600px;
}

th, td {
  border: 1px solid #aaa;
  padding: 8px 12px;
  text-align: left;
}

✅ Updated HTML Structure

Inside .table-wrapper, add .scroll-notice, .scroll-progress, then <table>:

<div class="table-wrapper">
  <div class="scroll-notice">Scroll to view</div>
  <div class="scroll-progress"></div>
  <table>
    <!-- table content -->
  </table>
</div>

Notice: .scroll-progress is between .scroll-notice and table.


✅ Updated jQuery Script

$(document).ready(function() {
    $("table").each(function() {
        var columnCount = $(this).find('tr:first-child td, tr:first-child th').length;

        if (columnCount > 5) {
            if (!$(this).parent().hasClass('table-wrapper')) {
                $(this).wrap("<div class='table-wrapper'></div>");
                $(this).before('<div class="scroll-notice" style="display:none;">Scroll to view ➡️</div><div class="scroll-progress"></div>');
            }
        }
    });

    function updateScrollNotices() {
        $(".table-wrapper").each(function() {
            var $wrapper = $(this);
            var $table = $wrapper.find('table');
            var $notice = $wrapper.find(".scroll-notice");

            if ($table.outerWidth() > $wrapper.width()) {
                $notice.show();
            } else {
                $notice.hide();
            }
        });
    }

    function updateProgressBar($wrapper) {
        var scrollLeft = $wrapper.scrollLeft();
        var scrollWidth = $wrapper.get(0).scrollWidth - $wrapper.width();
        var progress = (scrollLeft / scrollWidth) * 100;
        $wrapper.find('.scroll-progress').css('width', progress + "%");
    }

    updateScrollNotices();

    $(window).on('resize', function() {
        updateScrollNotices();
    });

    $(".table-wrapper").each(function() {
        var $wrapper = $(this);
        var $notice = $wrapper.find(".scroll-notice");
        var timer = null;

        $wrapper.on('scroll', function() {
            if ($notice.is(":visible")) {
                if (timer) {
                    clearTimeout(timer);
                }
                timer = setTimeout(function() {
                    $notice.fadeOut();
                }, 3000);
            }

            updateProgressBar($wrapper); // Update progress on scroll
        });

        // Initial progress update
        updateProgressBar($wrapper);
    });
});

Full Working Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sticky Scroll Notice for Wide Tables</title>
  <style>
    .table-wrapper {
	  overflow-x: auto;
	  max-width: 100%;
	  border: 2px solid #ccc;
	  margin: 20px 0;
	  padding-top: 30px;
	  position: relative;
	}

	.scroll-notice {
	  position: absolute;
	  top: 0;
	  left: 0;
	  background: #f9f9f9;
	  padding: 6px 10px;
	  font-size: 14px;
	  color: #555;
	  font-style: italic;
	  white-space: nowrap;
	  z-index: 10;
	  display: none;
	}

	.scroll-progress {
	  height: 4px;
	  background: linear-gradient(to right, #4caf50, #81c784);
	  width: 0%;
	  position: absolute;
	  top: 28px; /* adjust below notice */
	  left: 0;
	  transition: width 0.2s ease;
	  z-index: 5;
	}

	table {
	  border-collapse: collapse;
	  width: 100%;
	  min-width: 600px;
	}

	th, td {
	  border: 1px solid #aaa;
	  padding: 8px 12px;
	  text-align: left;
	}
  </style>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div class="table-wrapper">
  <div class="scroll-notice">Scroll to view ➡️</div>
  <div class="scroll-progress"></div>
	<table>
	  <tr>
		<th>Product</th><th>Price</th><th>Stock</th><th>SKU</th><th>Category</th><th>Brand</th>
	  </tr>
	  <tr>
		<td>Phone</td><td>$699</td><td>Available</td><td>PH1234</td><td>Electronics</td><td>Samsung</td>
	  </tr>
	  <tr>
		<td>Laptop</td><td>$999</td><td>Available</td><td>LT5678</td><td>Electronics</td><td>Dell</td>
	  </tr>
	</table>
</div>

<script>
$(document).ready(function() {
    $("table").each(function() {
        var columnCount = $(this).find('tr:first-child td, tr:first-child th').length;

        if (columnCount > 5) {
            if (!$(this).parent().hasClass('table-wrapper')) {
                $(this).wrap("<div class='table-wrapper'></div>");
                $(this).before('<div class="scroll-notice" style="display:none;">Scroll to view ➡️</div><div class="scroll-progress"></div>');
            }
        }
    });

    function updateScrollNotices() {
        $(".table-wrapper").each(function() {
            var $wrapper = $(this);
            var $table = $wrapper.find('table');
            var $notice = $wrapper.find(".scroll-notice");

            if ($table.outerWidth() > $wrapper.width()) {
                $notice.show();
            } else {
                $notice.hide();
            }
        });
    }

    function updateProgressBar($wrapper) {
        var scrollLeft = $wrapper.scrollLeft();
        var scrollWidth = $wrapper.get(0).scrollWidth - $wrapper.width();
        var progress = (scrollLeft / scrollWidth) * 100;
        $wrapper.find('.scroll-progress').css('width', progress + "%");
    }

    updateScrollNotices();

    $(window).on('resize', function() {
        updateScrollNotices();
    });

    $(".table-wrapper").each(function() {
        var $wrapper = $(this);
        var $notice = $wrapper.find(".scroll-notice");
        var timer = null;

        $wrapper.on('scroll', function() {
            if ($notice.is(":visible")) {
                if (timer) {
                    clearTimeout(timer);
                }
                timer = setTimeout(function() {
                    $notice.fadeOut();
                }, 3000);
            }

            updateProgressBar($wrapper); // Update progress on scroll
        });

        // Initial progress update
        updateProgressBar($wrapper);
    });
});
</script>
</body>
</html>

Live Result:

✅ Sticky "Scroll to view ➡️" notice
✅ Auto-hide after scroll
✅ Cool horizontal scroll progress bar grows as user scrolls
✅ Fully responsive, smooth and dynamic


UX Tips:

  • Gradient Bar:
    Using a gradient (linear-gradient) looks much cooler than a flat color.

  • Smooth Animation:
    transition: width 0.2s ease makes the bar animation smooth.

  • Progress Visibility:
    Place the progress bar just below the scroll-notice so it's clearly visible.


Common Pitfalls:

  • Wrong context:
    Always calculate scroll inside .table-wrapper, not the entire page scroll.

  • Reset progress:
    On window resize, tables might change size — you can refresh progress if needed.


Now Your Tables Are FULLY Interactive and PRO-Level!


Would you like me to show one final ultra-pro tip?
Adding a "Back to Start ⇤" button if user scrolls far to the right! 
(like a floating button that appears when needed)

Click here
(It's super sleek for huge tables!)