Learn how to create dot navigation with the active section highlighted as you scroll in Webflow.
In this tutorial, Sandro, cofounder of the Gemeos Webflow agency, shows you how to create a section progress bar (dot navigation) in Webflow, with the active dot highlighted as you scroll.
Example
Scroll through the area — the dots on the right show your position
Introduction
Webflow is a no-code tool that generates clean HTML, CSS, and JavaScript without writing a single line of code.
Features
Visual designer, built-in CMS, native animations, hosting included, and one-click deployment.
Performance
Built-in Fastly CDN, automatically optimized images, and excellent Core Web Vitals by default.
Pricing
Plans start at €14/month. Hosting and CMS included, with no maintenance or plugin fees.
Conclusion
Webflow is the best choice for agencies and marketing teams that want performance and independence.
Active section: Introduction
| Attribute | Element | Example value |
|---|
| data-progress-section | Webflow section | Section name (e.g. 'Introduction') |
| id='section-progress' | Container div | Injected as fixed right by the script |
1. Add the attributes to your sections
On each section of your page, add the custom attribute data-progress-section with the section name as the value (e.g. Introduction, Features...). These names appear in a tooltip when you hover over the dots.
2. Create the container in Webflow
Create an empty Div with the ID section-progress. The script will handle its position (fixed right, vertically centered). You can leave it anywhere in the DOM.
3. Add the script in Footer code
(function() {
var sections = document.querySelectorAll('[data-progress-section]');
var container = document.getElementById('section-progress');
if (!sections.length || !container) return;
var dots = [];
container.style.cssText = 'position:fixed;right:24px;top:50%;transform:translateY(-50%);' +
'display:flex;flex-direction:column;gap:8px;z-index:999;';
sections.forEach(function(section, i) {
var dot = document.createElement('div');
dot.style.cssText = 'width:8px;height:8px;border-radius:50%;background:#e5e7eb;' +
'transition:all 0.3s;cursor:pointer;';
dot.title = section.dataset.progressSection || ('Section ' + (i + 1));
dot.addEventListener('click', function() {
section.scrollIntoView({ behavior: 'smooth' });
});
container.appendChild(dot);
dots.push(dot);
});
function update() {
var active = 0;
sections.forEach(function(s, i) {
if (s.getBoundingClientRect().top <= window.innerHeight / 2) active = i;
});
dots.forEach(function(d, i) {
var isActive = i === active;
d.style.background = isActive ? '#a78bfa' : i < active ? '#d4b8fc' : '#e5e7eb';
d.style.width = isActive ? '10px' : '8px';
d.style.height = isActive ? '10px' : '8px';
});
}
update();
window.addEventListener('scroll', update, { passive: true });
})();
good to know
On mobile, dot navigation takes up space and can get in the way. Hide it with @media (max-width: 768px) { #section-progress { display: none !important; } }. On desktop with lots of sections (10+), reduce the dot size to 6px and the spacing to 6px so the navigation doesn't run off the screen.
Conclusion
Dot navigation is a classic for landing pages and one-pagers. Use cases:
- Landing pages with clearly defined sections
- One-page showcase or portfolio sites
- Articles with long chapters
Scroll through the area to see the dots update
Section 1 — Introduction
The content for this section appears here.
Section 2 — Features
The main features are described here.
Section 3 — Pricing
The plans and pricing are shown here.
Section 4 — Contact
The contact form is here.