Onepager met scroll-snap in een kader Nieuw
Een korte praktijksite in vier schermen die per scherm vastklikken met scroll-snap (mandatory, snap-stop always). Rechts een sectiekeuze met aria-current die meeloopt via IntersectionObserver; klikken springt naar de sectie, het kader is met het toetsenbord te scrollen. Voor een praktijk, salon of evenement waar vier vlakken het hele verhaal vertellen.

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
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- 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'));
Meer uit scroll-effecten
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →