Onepager met scroll-snap in een kader New
A short practice website in four screens that snap into place with scroll-snap (mandatory, snap-stop always). On the right a section picker with aria-current that follows via IntersectionObserver; clicking jumps to the section, the frame scrolls with the keyboard. For a practice, salon or event where four panels tell the whole story.

Waarvoor je bij ons komt
- Rug- en nekklachten
- Sportblessures
- Revalidatie na een operatie
- Bekkenfysiotherapie
Geen verwijzing nodig.
Binnen een week je eerste afspraak
Je boekt online of belt, wij bellen binnen één werkdag terug en zien je dezelfde week voor een intake van 45 minuten.
Langskomen of bellen
Biltstraat 112, 3572 BJ Utrecht
Maandag tot en met vrijdag 7:30 tot 21:00
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.
<!-- Onepager met scroll-snap in een kader · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="sno">
<div class="sno__vp" tabindex="0" aria-label="Fysio Oost, scroll door vier schermen">
<section class="sno__s sno__s--foto" aria-label="Welkom"><img class="sno__img" src="https://neddev.com/lab-media/snap-onepager-1.webp" alt="" width="800" height="436"><div class="sno__in"><h3 class="sno__h">Weer zonder pijn bewegen</h3><p class="sno__p">Fysio Oost, Biltstraat 112 in Utrecht</p><a class="sno__btn" href="#snap-onepager">Plan een intake</a></div></section>
<section class="sno__s" aria-label="Behandelingen"><div class="sno__in"><h3 class="sno__h">Waarvoor je bij ons komt</h3><ul class="sno__ul"><li>Rug- en nekklachten</li><li>Sportblessures</li><li>Revalidatie na een operatie</li><li>Bekkenfysiotherapie</li></ul><p class="sno__p">Geen verwijzing nodig.</p></div></section>
<section class="sno__s sno__s--oranje" aria-label="Werkwijze"><div class="sno__in"><h3 class="sno__h">Binnen een week je eerste afspraak</h3><p class="sno__p">Je boekt online of belt, wij bellen binnen één werkdag terug en zien je dezelfde week voor een intake van 45 minuten.</p></div></section>
<section class="sno__s sno__s--zwart" aria-label="Contact"><div class="sno__in"><h3 class="sno__h">Langskomen of bellen</h3><p class="sno__p">Biltstraat 112, 3572 BJ Utrecht<br>Maandag tot en met vrijdag 7:30 tot 21:00</p><a class="sno__btn" href="tel:0301234567">Bel 030 123 4567</a></div></section>
</div>
<div class="sno__nav" role="group" aria-label="Ga naar scherm"></div>
</div>
</div>/* Onepager met scroll-snap in een kader · NedDev · eigen werk. */
.sno{position:absolute;inset:0;padding:8px;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;background:#f4f3f1;text-align:left}
.sno *{box-sizing:border-box}
.sno__vp{position:relative;width:100%;height:100%;overflow-y:auto;scroll-snap-type:y mandatory;overscroll-behavior:contain;border:1px solid #0a0a0a;border-radius:8px;scrollbar-width:none;background:#fff}
.sno__vp::-webkit-scrollbar{display:none}
.sno__vp:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.sno__s{position:relative;height:100%;scroll-snap-align:start;scroll-snap-stop:always;display:flex;align-items:flex-end;padding:16px 44px 16px 16px;overflow:hidden}
.sno__in{position:relative;max-width:30em}
.sno__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.sno__s--foto::after{content:'';position:absolute;inset:0;background:linear-gradient(0deg,rgba(10,10,10,.78),rgba(10,10,10,.1) 70%)}
.sno__s--foto .sno__in{z-index:1;color:#fff}
.sno__s--foto .sno__p{color:#ebe8e3}
.sno__s--oranje{background:#F5480F}
.sno__s--zwart{background:#0a0a0a;color:#fff}
.sno__s--zwart .sno__p{color:#d8d5cf}
.sno__h{margin:0;font-size:clamp(18px,5.6cqi,26px);line-height:1.08;font-weight:700;letter-spacing:-.02em}
.sno{container-type:inline-size}
.sno__p{margin:6px 0 0;font-size:12.5px;line-height:1.45;color:#2a2a2a}
.sno__ul{margin:8px 0 0;padding:0 0 0 16px;font-size:13px;line-height:1.5}
.sno__btn{display:inline-flex;align-items:center;min-height:32px;margin-top:9px;padding:0 12px;border-radius:4px;background:#F5480F;color:#0a0a0a;font-size:12.5px;font-weight:600;text-decoration:none}
.sno__s--zwart .sno__btn{background:#fff}
.sno__btn:hover{background:#fff;color:#0a0a0a}
.sno__s--zwart .sno__btn:hover{background:#F5480F}
.sno__btn:focus-visible{outline:2px solid #fff;outline-offset:2px}
.sno__nav{position:absolute;right:14px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:2px;z-index:2}
.sno__sro{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.sno__dot{position:relative;width:24px;height:24px;display:grid;place-items:center;padding:0;border:0;background:transparent;cursor:pointer;border-radius:4px}
.sno__dot::before{content:'';width:8px;height:8px;border-radius:50%;background:#fff;box-shadow:0 0 0 1.5px #0a0a0a;transition:height .2s,border-radius .2s}
.sno__dot[aria-current="true"]::before{height:18px;border-radius:4px;background:#0a0a0a;box-shadow:0 0 0 1.5px #fff}
.sno__dot:focus-visible{outline:2px solid #F5480F;outline-offset:0}
@media (prefers-reduced-motion:reduce){.sno__dot::before{transition:none}}// Onepager met scroll-snap in een kader · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w = root.querySelector('.sno'), vp = w.querySelector('.sno__vp'), nav = w.querySelector('.sno__nav');
var rm = matchMedia('(prefers-reduced-motion: reduce)').matches;
var secs = [].slice.call(vp.querySelectorAll('.sno__s'));
w.querySelector('.sno__btn').addEventListener('click', function (e) { e.preventDefault(); go(3); });
var dots = secs.map(function (s, i) {
var b = document.createElement('button'); b.type = 'button'; b.className = 'sno__dot'; b.innerHTML = '<span class="sno__sro"></span>'; b.firstChild.textContent = s.getAttribute('aria-label');
b.addEventListener('click', function () { go(i); }); nav.appendChild(b); return b;
});
function mark(i) { dots.forEach(function (d, k) { if (k === i) d.setAttribute('aria-current', 'true'); else d.removeAttribute('aria-current'); }); }
function go(i) { vp.scrollTo({ top: secs[i].offsetTop, behavior: rm ? 'auto' : 'smooth' }); mark(i); }
mark(0);
var io = 'IntersectionObserver' in window ? new IntersectionObserver(function (es) { es.forEach(function (e) { if (e.isIntersecting) mark(secs.indexOf(e.target)); }); }, { root: vp, threshold: .6 }) : null;
if (io) secs.forEach(function (s) { io.observe(s); });
}
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 →