Vloeiend scrollen (Lenis-basis) New
Smooth scrolling as a base module inside its own scroll area: loads Lenis 1.3 (MIT) from jsdelivr and falls back to a 30-line custom variant. Anchor links ease along, an inner list with data-lenis-prevent scrolls natively and prefers-reduced-motion keeps native scrolling. Use it on story-driven pages with scroll animations, not on shops with long lists or form pages.
Bakkerij Van Dam · Haarlem, sinds 1962
Desembrood, elke ochtend om 6:30 uit de oven.
[ 01 ] Brood
- Desem wit€ 4,20
- Spelt volkoren€ 4,60
- Roggebrood Fries€ 3,85
- Krentenbol, per 6€ 3,90
[ 02 ] Taart bestellen
Bestel uiterlijk twee dagen vooraf. Slagroomtaart voor 8 personen € 24,50, ophalen vanaf 8:00.
[ 03 ] Openingstijden
Eigen scrollvlak met data-lenis-prevent:
- ma 7:30 tot 18:00
- di 7:30 tot 18:00
- wo 7:30 tot 18:00
- do 7:30 tot 18:00
- vr 7:30 tot 19:00
- za 7:00 tot 17:00
- zo gesloten
- 2e kerstdag 9:00 tot 13:00
[ 04 ] Wanneer wel, wanneer niet
Wel: verhalende pagina's waar scrollanimaties (GSAP, scroll-timeline) dezelfde, rustige scrollwaarde moeten lezen.
Niet: webshops met lange productlijsten, formulierpagina's of pagina's zonder scrollanimatie. Dan voelt het alleen trager.
Altijd: uit bij prefers-reduced-motion, en binnenpanelen markeren met data-lenis-prevent.
How to use it
- Paste the HTML where the scroll effects 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.
<!-- Vloeiend scrollen (Lenis-basis) · Bron: Lenis (darkroom.engineering) · licentie MIT. Laat deze vermelding staan bij hergebruik. -->
<div class="jouw-container">
<div class="lnb">
<div class="lnb__bar"><span class="lnb__st" role="status">Lenis laden</span><button class="lnb__tg" type="button" aria-pressed="true">Vloeiend aan</button></div>
<div class="lnb__sc" tabindex="0" aria-label="Voorbeeldpagina Bakkerij Van Dam"><div class="lnb__in">
<p class="lnb__k">Bakkerij Van Dam · Haarlem, sinds 1962</p>
<h4 class="lnb__h">Desembrood, elke ochtend om 6:30 uit de oven.</h4>
<nav class="lnb__nav" aria-label="Op deze pagina"><a href="#brood" data-to="brood">Brood</a><a href="#taart" data-to="taart">Taart bestellen</a><a href="#tijden" data-to="tijden">Openingstijden</a><a href="#wanneer" data-to="wanneer">Wanneer wel</a></nav>
<div class="lnb__s" data-sec="brood" tabindex="-1"><p class="lnb__sk">[ 01 ] Brood</p><ul class="lnb__ul"><li><span>Desem wit</span><span>€ 4,20</span></li><li><span>Spelt volkoren</span><span>€ 4,60</span></li><li><span>Roggebrood Fries</span><span>€ 3,85</span></li><li><span>Krentenbol, per 6</span><span>€ 3,90</span></li></ul></div>
<div class="lnb__s" data-sec="taart" tabindex="-1"><p class="lnb__sk">[ 02 ] Taart bestellen</p><p>Bestel uiterlijk twee dagen vooraf. Slagroomtaart voor 8 personen € 24,50, ophalen vanaf 8:00.</p></div>
<div class="lnb__s" data-sec="tijden" tabindex="-1"><p class="lnb__sk">[ 03 ] Openingstijden</p><p class="lnb__mini">Eigen scrollvlak met data-lenis-prevent:</p>
<ul class="lnb__lijst" data-lenis-prevent tabindex="0" aria-label="Openingstijden per dag"><li>ma 7:30 tot 18:00</li><li>di 7:30 tot 18:00</li><li>wo 7:30 tot 18:00</li><li>do 7:30 tot 18:00</li><li>vr 7:30 tot 19:00</li><li>za 7:00 tot 17:00</li><li>zo gesloten</li><li>2e kerstdag 9:00 tot 13:00</li></ul></div>
<div class="lnb__s" data-sec="wanneer" tabindex="-1"><p class="lnb__sk">[ 04 ] Wanneer wel, wanneer niet</p>
<p><b>Wel:</b> verhalende pagina's waar scrollanimaties (GSAP, scroll-timeline) dezelfde, rustige scrollwaarde moeten lezen.</p>
<p><b>Niet:</b> webshops met lange productlijsten, formulierpagina's of pagina's zonder scrollanimatie. Dan voelt het alleen trager.</p>
<p><b>Altijd:</b> uit bij prefers-reduced-motion, en binnenpanelen markeren met data-lenis-prevent.</p></div>
</div></div></div>
</div>/* Vloeiend scrollen (Lenis-basis) · Bron: Lenis (darkroom.engineering) · licentie MIT. Laat deze vermelding staan bij hergebruik. */
.lnb{position:absolute;inset:0;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',system-ui,sans-serif;display:flex;flex-direction:column;container-type:size}
.lnb__bar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 10px;border-bottom:1px solid rgba(10,10,10,.12);background:#fff}
.lnb__st{font:500 10.5px/1.2 'JetBrains Mono',monospace;letter-spacing:.02em;color:#3d3d3d;display:inline-flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lnb__st::before{content:'';width:7px;height:7px;border-radius:50%;background:#9a9a9a;flex:none}
.lnb.is-aan .lnb__st::before{background:#1f8a4c}
.lnb__tg{flex:none;font:600 11px/1 'Switzer',sans-serif;padding:6px 10px;border:1px solid #0a0a0a;border-radius:999px;background:#0a0a0a;color:#fff;cursor:pointer;transition:background .18s,color .18s}
.lnb__tg[aria-pressed="false"]{background:#fff;color:#0a0a0a}
.lnb__tg:hover{background:#F5480F;border-color:#F5480F;color:#fff}
.lnb__tg:focus-visible,.lnb__sc:focus-visible,.lnb__lijst:focus-visible,.lnb__nav a:focus-visible,.lnb__s:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.lnb__tg:disabled{opacity:.45;cursor:not-allowed;background:#fff;color:#0a0a0a;border-color:#0a0a0a}
.lnb__sc{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;position:relative}
.lnb__sc.lenis-smooth{scroll-behavior:auto!important}
.lnb [data-lenis-prevent]{overscroll-behavior:contain}
.lnb__in{position:relative;padding:14px 14px 40cqh}
.lnb__k{font:500 10px 'JetBrains Mono',monospace;text-transform:uppercase;letter-spacing:.08em;color:#666;margin:0 0 6px}
.lnb__h{font:700 clamp(17px,6cqi,30px)/1.08 'Switzer',sans-serif;letter-spacing:-.02em;margin:0 0 10px;max-width:22ch}
.lnb__nav{display:flex;flex-wrap:wrap;gap:5px;margin:0 0 14px}
.lnb__nav a{font:500 11px/1 'Switzer',sans-serif;color:#0a0a0a;text-decoration:none;padding:6px 9px;border:1px solid rgba(10,10,10,.2);border-radius:999px;background:#fff;transition:border-color .18s,color .18s}
.lnb__nav a:hover{border-color:#F5480F;color:#b8330a}
.lnb__s{background:#fff;border-radius:4px;padding:12px 12px 10px;margin:0 0 10px;min-height:46cqh;font-size:12.5px;line-height:1.5}
.lnb__s p{margin:0 0 6px}
.lnb__sk{font:600 10.5px 'JetBrains Mono',monospace!important;letter-spacing:.06em;text-transform:uppercase;color:#b8330a;margin:0 0 8px!important}
.lnb__ul{list-style:none;margin:0;padding:0}
.lnb__ul li{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px solid rgba(10,10,10,.08);font-variant-numeric:tabular-nums}
.lnb__mini{font:500 10px 'JetBrains Mono',monospace;color:#666}
.lnb__lijst{list-style:none;margin:0;padding:6px 10px;max-height:78px;overflow:auto;border:1px dashed rgba(10,10,10,.3);border-radius:3px;font-variant-numeric:tabular-nums}
.lnb__lijst li{padding:2px 0}// Vloeiend scrollen (Lenis-basis) · Bron: Lenis (darkroom.engineering) · licentie MIT. Laat deze vermelding staan bij hergebruik.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.lnb')||root;
var sc=root.querySelector('.lnb__sc'),inner=root.querySelector('.lnb__in'),st=root.querySelector('.lnb__st'),tg=root.querySelector('.lnb__tg');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,eng=null,Lenis=null;
function say(t){st.textContent=t;}
function maxS(){return sc.scrollHeight-sc.clientHeight;}
function own(){var target=sc.scrollTop,cur=target,run=false,alive=true;
function tick(){if(!alive){run=false;return;}cur+=(target-cur)*.12;if(Math.abs(target-cur)<.4){cur=target;run=false;}sc.scrollTop=cur;if(run)requestAnimationFrame(tick);}
function go(){if(!run){run=true;cur=sc.scrollTop;requestAnimationFrame(tick);}}
function wheel(e){if(e.ctrlKey||e.target.closest('[data-lenis-prevent]'))return;var d=e.deltaY*(e.deltaMode===1?16:e.deltaMode===2?sc.clientHeight:1);
if((sc.scrollTop<=0&&d<0)||(sc.scrollTop>=maxS()-1&&d>0))return;e.preventDefault();target=Math.max(0,Math.min(maxS(),target+d));go();}
function sync(){if(!run){target=cur=sc.scrollTop;}}
sc.addEventListener('wheel',wheel,{passive:false});sc.addEventListener('scroll',sync,{passive:true});
return {name:'eigen mini-variant',to:function(el){target=Math.max(0,Math.min(maxS(),el.offsetTop-8));go();},destroy:function(){alive=false;sc.removeEventListener('wheel',wheel);sc.removeEventListener('scroll',sync);}};}
function lenisEng(){var l=new Lenis({wrapper:sc,content:inner,lerp:.1,smoothWheel:true,autoRaf:true});
return {name:'Lenis '+(l.version||'1.3'),to:function(el){l.scrollTo(el,{offset:-8});},destroy:function(){l.destroy();}};}
function start(){if(rm){say('Uit: systeem vraagt minder beweging');tg.disabled=true;tg.textContent='Vloeiend uit';tg.setAttribute('aria-pressed','false');return;}
try{eng=Lenis?lenisEng():own();}catch(e){eng=own();}
root.classList.add('is-aan');say('Actief: '+eng.name);tg.setAttribute('aria-pressed','true');tg.textContent='Vloeiend aan';}
function stop(){if(eng){eng.destroy();eng=null;}root.classList.remove('is-aan');say('Uit: gewone browserscroll');tg.setAttribute('aria-pressed','false');tg.textContent='Vloeiend uit';}
tg.addEventListener('click',function(){if(eng)stop();else start();});
// op de randen het wiel doorgeven aan de pagina, zodat het demovlak de pagina niet vasthoudt
root.addEventListener('wheel',function(e){if(!eng)return;var m=maxS();if((sc.scrollTop<=0&&e.deltaY<0)||(sc.scrollTop>=m-1&&e.deltaY>0))e.stopPropagation();},true);
root.querySelectorAll('[data-to]').forEach(function(a){a.addEventListener('click',function(e){e.preventDefault();var t=inner.querySelector('[data-sec="'+a.getAttribute('data-to')+'"]');if(!t)return;
if(eng)eng.to(t);else sc.scrollTop=t.offsetTop-8;t.focus({preventScroll:true});});});
if(rm){start();}else{var klaar=false,wacht=setTimeout(function(){if(!klaar){klaar=true;start();}},2500);
import('https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.mjs').then(function(m){Lenis=m.default||m.Lenis||null;}).catch(function(){}).then(function(){if(klaar)return;klaar=true;clearTimeout(wacht);start();});}
}
init(document.querySelector('.jouw-container'));
More scroll effects
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 →