Scroll-spy inhoudsopgave New
A table of contents that follows the article: an orange line fills with your reading progress and the current step lights up. For long service pages and guides.
Zo verloopt uw verbouwing
1. Kennismaking
Een gesprek van een half uur, aan de telefoon of bij u thuis. We horen wat u wilt en geven direct een eerlijke indicatie of het past binnen uw budget.
2. Opname
Onze calculator meet alles in en kijkt naar fundering, leidingen en draagmuren. Daarna weten we wat er echt nodig is, en wat niet.
3. Offerte
Binnen vijf werkdagen ligt er een offerte met vaste prijs. Meerwerk ontstaat alleen als u zelf iets wilt toevoegen.
4. Uitvoering
Elke vrijdag ontvangt u een korte update met foto's. Uw uitvoerder is elke werkdag bereikbaar op een vast nummer.
5. Oplevering
We lopen samen alles na en noteren de puntjes op de i. Die zijn binnen twee weken opgelost, daarna volgt de eindafrekening.
How to use it
- Paste the HTML where the navigation & menus should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Scroll-spy inhoudsopgave · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="sst"><div class="sst__toc"><span class="sst__lbl">Op deze pagina</span><div class="sst__rail"><span class="sst__fill"></span></div><ol class="sst__ol">
<li><a href="#" data-t="0"><span>1</span>Kennismaking</a></li><li><a href="#" data-t="1"><span>2</span>Opname</a></li><li><a href="#" data-t="2"><span>3</span>Offerte</a></li><li><a href="#" data-t="3"><span>4</span>Uitvoering</a></li><li><a href="#" data-t="4"><span>5</span>Oplevering</a></li></ol></div>
<div class="sst__art" tabindex="0" aria-label="Artikel: zo verloopt uw verbouwing"><h4 class="sst__h">Zo verloopt uw verbouwing</h4>
<div class="sst__sec"><h5>1. Kennismaking</h5><p>Een gesprek van een half uur, aan de telefoon of bij u thuis. We horen wat u wilt en geven direct een eerlijke indicatie of het past binnen uw budget.</p></div>
<div class="sst__sec"><h5>2. Opname</h5><p>Onze calculator meet alles in en kijkt naar fundering, leidingen en draagmuren. Daarna weten we wat er echt nodig is, en wat niet.</p></div>
<div class="sst__sec"><h5>3. Offerte</h5><p>Binnen vijf werkdagen ligt er een offerte met vaste prijs. Meerwerk ontstaat alleen als u zelf iets wilt toevoegen.</p></div>
<div class="sst__sec"><h5>4. Uitvoering</h5><p>Elke vrijdag ontvangt u een korte update met foto's. Uw uitvoerder is elke werkdag bereikbaar op een vast nummer.</p></div>
<div class="sst__sec"><h5>5. Oplevering</h5><p>We lopen samen alles na en noteren de puntjes op de i. Die zijn binnen twee weken opgelost, daarna volgt de eindafrekening.</p></div></div></div>
</div>/* Scroll-spy inhoudsopgave · NedDev · eigen werk. */
.sst{position:absolute;inset:0;background:#fff;color:#0a0a0a;font-family:'Switzer',system-ui,sans-serif;display:grid;grid-template-columns:34% 1fr;container-type:inline-size}
.sst__toc{position:relative;padding:14px 10px 14px 14px;background:#f4f3f1;border-right:1px solid #e6e3de}
.sst__lbl{display:block;font:500 9.5px 'JetBrains Mono',monospace;letter-spacing:.1em;text-transform:uppercase;color:#8a857f;margin-bottom:10px}
.sst__rail{position:absolute;left:14px;top:36px;bottom:14px;width:2px;background:#dcd8d2;border-radius:2px;overflow:hidden}
.sst__fill{position:absolute;left:0;top:0;width:100%;height:100%;background:#F5480F;transform-origin:top;transform:scaleY(0)}
.sst__ol{list-style:none;margin:0;padding:0 0 0 12px;display:flex;flex-direction:column;gap:2px}
.sst__ol a{display:flex;gap:7px;align-items:baseline;padding:4px 4px;border-radius:4px;text-decoration:none;color:#8a857f;font-size:12px;font-weight:500;transition:color .25s,background .25s,transform .25s}
.sst__ol a span{font:500 9.5px 'JetBrains Mono',monospace}
.sst__ol a:hover{color:#0a0a0a}.sst__ol a:focus-visible{outline:2px solid #F5480F;outline-offset:-2px}
.sst__ol a.is-on{color:#0a0a0a;font-weight:700;background:#fff;transform:translateX(2px)}
.sst__ol a.is-on span{color:#F5480F}
.sst__ol a.is-done{color:#3c3935}
.sst__art{overflow-y:auto;padding:14px 16px 60px;scrollbar-width:thin;outline:none}
.sst__h{margin:0 0 6px;font:700 17px/1.15 'Switzer',sans-serif;letter-spacing:-.02em}
.sst__sec{padding:8px 0;border-top:1px solid #eeebe7}
.sst__sec h5{margin:0 0 3px;font-size:13px;font-weight:700}
.sst__sec p{margin:0;font-size:12px;line-height:1.55;color:#4b4843}
@container (max-width:380px){.sst{grid-template-columns:37% 1fr}.sst__toc{padding:12px 6px 12px 12px}.sst__rail{left:12px}.sst__lbl{font-size:8.5px;white-space:nowrap;letter-spacing:.04em}.sst__ol{padding-left:8px}.sst__ol a{font-size:10.5px;gap:4px;padding:4px 3px}.sst__ol a.is-on{transform:none}.sst__art{padding:12px}}// Scroll-spy inhoudsopgave · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.sst')||root;
var art=root.querySelector('.sst__art'),secs=[].slice.call(root.querySelectorAll('.sst__sec')),ls=[].slice.call(root.querySelectorAll('.sst__ol a')),fill=root.querySelector('.sst__fill');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,auto=!rm,pos=0,hold=0,raf=0;
function upd(){var st=art.scrollTop,max=art.scrollHeight-art.clientHeight,p=max>0?st/max:0;var act=0;
secs.forEach(function(s,i){if(s.offsetTop-art.offsetTop<=st+art.clientHeight*.35)act=i;});if(p>.985)act=secs.length-1;
ls.forEach(function(a,i){a.classList.toggle('is-on',i===act);a.classList.toggle('is-done',i<act);if(i===act)a.setAttribute('aria-current','true');else a.removeAttribute('aria-current');});
fill.style.transform='scaleY('+p.toFixed(4)+')';}
art.addEventListener('scroll',upd,{passive:true});
ls.forEach(function(a,i){a.addEventListener('click',function(e){e.preventDefault();stop();art.scrollTo({top:secs[i].offsetTop-art.offsetTop-6,behavior:rm?'auto':'smooth'});});});
function stop(){auto=false;cancelAnimationFrame(raf);}
['wheel','touchstart','pointerdown','keydown'].forEach(function(ev){root.addEventListener(ev,stop,{passive:true});});
function drift(){if(!auto)return;var max=art.scrollHeight-art.clientHeight;if(hold>0){hold--;}else{pos+=.45;if(pos>=max){pos=max;hold=90;art.scrollTop=pos;raf=requestAnimationFrame(function back(){if(!auto)return;if(hold>0){hold--;raf=requestAnimationFrame(back);return;}art.scrollTo({top:0,behavior:'smooth'});pos=0;hold=70;raf=requestAnimationFrame(drift);});return;}art.scrollTop=pos;}raf=requestAnimationFrame(drift);}
upd();if(auto){hold=40;raf=requestAnimationFrame(drift);}
}
init(document.querySelector('.jouw-container'));
More navigation & menus
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →