
Adding a Scroll Progress Bar Above Tables in jQuery
Last updated 3 weeks, 5 days ago | 40 views 75 5

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:
-
Add a small progress bar above the wide table.
-
As users scroll horizontally, the bar fills to show how far they've scrolled.
-
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!)