Foto-slideshow met pauzeknop New
Full-bleed photo slideshow with a calm crossfade, an always visible pause button (WCAG 2.2.2), prev/next, arrow keys and swipe. Stops when off-screen, in a hidden tab and on hover or focus. Uses IntersectionObserver and pointer events; with reduced motion it starts paused and swaps without a transition.
Slapen achter de duinen
Twaalf houten huisjes bij Domburg, vijf minuten lopen naar het strand.
Bekijk beschikbaarheidHow to use it
- Paste the HTML where the hero styles 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.
<!-- Foto-slideshow met pauzeknop · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="hss" role="region" aria-roledescription="carrousel" aria-label="Foto's van Duinhuisjes Domburg">
<div class="hss__slides" aria-live="off">
<div class="hss__slide is-on" role="group" aria-roledescription="dia" aria-label="1 van 4"><img src="https://neddev.com/lab-media/hero-slideshow-1.webp" alt="Houten vakantiehuisje tussen de duinen bij Domburg" width="1584" height="672"></div>
<div class="hss__slide" role="group" aria-roledescription="dia" aria-label="2 van 4" aria-hidden="true"><img src="https://neddev.com/lab-media/hero-slideshow-2.webp" alt="Lichte woonkamer met houtkachel en uitzicht op de duinen" width="1376" height="768" loading="lazy"></div>
<div class="hss__slide" role="group" aria-roledescription="dia" aria-label="3 van 4" aria-hidden="true"><img src="https://neddev.com/lab-media/hero-slideshow-3.webp" alt="Leeg strand met paalhoofden bij zonsopkomst" width="1584" height="672" loading="lazy"></div>
<div class="hss__slide" role="group" aria-roledescription="dia" aria-label="4 van 4" aria-hidden="true"><img src="https://neddev.com/lab-media/hero-slideshow-4.webp" alt="Houten terras met twee fietsen en uitzicht over de duinen" width="1376" height="768" loading="lazy"></div>
</div>
<div class="hss__shade" aria-hidden="true"></div>
<div class="hss__txt">
<h2 class="hss__h">Slapen achter de duinen</h2>
<p class="hss__p">Twaalf houten huisjes bij Domburg, vijf minuten lopen naar het strand.</p>
<a class="hss__cta" href="#hero-slideshow">Bekijk beschikbaarheid</a>
</div>
<div class="hss__ctrl">
<button class="hss__btn hss__pause" type="button" aria-label="Slideshow pauzeren"><svg class="hss__ic-pause" viewBox="0 0 16 16" aria-hidden="true"><path d="M5 3v10M11 3v10"/></svg><svg class="hss__ic-play" viewBox="0 0 16 16" aria-hidden="true"><path d="M5 3l8 5-8 5z"/></svg></button>
<button class="hss__btn hss__prev" type="button" aria-label="Vorige foto"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 3L5 8l5 5"/></svg></button>
<span class="hss__count" aria-hidden="true">1 / 4</span>
<button class="hss__btn hss__next" type="button" aria-label="Volgende foto"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 3l5 5-5 5"/></svg></button>
</div>
</div>
</div>/* Foto-slideshow met pauzeknop · NedDev · eigen werk. */
.hss{position:absolute;inset:0;overflow:hidden;background:#1d2421;color:#fff;font-family:'Switzer',sans-serif;container-type:size;touch-action:pan-y;text-align:left}
.hss *,.hss *::before,.hss *::after{box-sizing:border-box}
.hss__slides{position:absolute;inset:0}
.hss__slide{position:absolute;inset:0;opacity:0;transition:opacity .9s ease}
.hss__slide.is-on{opacity:1}
.hss__slide img{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-drag:none;user-select:none;transform:scale(1.04);transition:transform 6s cubic-bezier(.2,.6,.3,1)}
.hss__slide.is-on img{transform:scale(1)}
.hss__shade{position:absolute;inset:0;background:linear-gradient(0deg,rgba(10,10,10,.74),rgba(10,10,10,.18) 58%,rgba(10,10,10,0) 80%);pointer-events:none}
.hss__txt{position:absolute;left:20px;right:170px;bottom:18px;display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.hss__h{margin:0;font:700 clamp(20px,7.4cqi,44px)/1.02 'Switzer',sans-serif;letter-spacing:-.025em;text-wrap:balance}
.hss__p{margin:0;font:400 clamp(12px,3.1cqi,16px)/1.4 'Switzer',sans-serif;color:#eceae6;max-width:30em}
.hss__cta{margin-top:4px;padding:9px 14px;background:#F5480F;color:#0a0a0a;border-radius:4px;font:600 13px/1 'Switzer',sans-serif;text-decoration:none;transition:background-color .16s}
.hss__cta:hover{background:#ff6a36}
.hss__cta:active{transform:translateY(1px)}
.hss__cta:focus-visible{outline:2px solid #fff;outline-offset:3px}
.hss__ctrl{position:absolute;right:16px;bottom:18px;display:flex;align-items:center;gap:6px}
.hss__btn{width:34px;height:34px;display:grid;place-items:center;margin:0;padding:0;border:1px solid rgba(255,255,255,.62);border-radius:4px;background:rgba(10,10,10,.45);color:#fff;cursor:pointer;transition:background-color .16s,border-color .16s}
.hss__btn:hover{background:rgba(10,10,10,.78);border-color:#fff}
.hss__btn:active{transform:translateY(1px)}
.hss__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.hss__btn svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.hss__ic-play{display:none}
.hss.is-paused .hss__ic-pause{display:none}
.hss.is-paused .hss__ic-play{display:block}
.hss.is-paused .hss__ic-play path{fill:currentColor}
.hss__count{min-width:36px;text-align:center;font:500 12px/1 'Switzer',sans-serif;font-variant-numeric:tabular-nums}
@container (max-width:460px){.hss__txt{left:16px;right:16px;bottom:60px}.hss__ctrl{left:16px;right:auto;bottom:14px}}
@container (max-width:360px){.hss__p{display:none}.hss__cta{padding:8px 12px;font-size:12px}}
@media (prefers-reduced-motion:reduce){.hss__slide,.hss__slide img{transition:none}.hss__slide img{transform:none}}// Foto-slideshow met pauzeknop · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.hss');if(!w)return;
var slides=[].slice.call(w.querySelectorAll('.hss__slide')),n=slides.length,i=0;
var cnt=w.querySelector('.hss__count'),live=w.querySelector('.hss__slides'),pb=w.querySelector('.hss__pause');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches;
var userPaused=rm,inView=false,hover=false,focus=false,timer=null,DUR=5200;
function show(k){i=(k+n)%n;slides.forEach(function(s,j){var on=j===i;s.classList.toggle('is-on',on);s.setAttribute('aria-hidden',on?'false':'true');var im=s.querySelector('img');if(on&&im)im.loading='eager';});cnt.textContent=(i+1)+' / '+n;}
function running(){return !userPaused&&inView&&!hover&&!focus&&!document.hidden;}
function sync(){clearInterval(timer);timer=null;var r=running();if(r)timer=setInterval(function(){show(i+1);},DUR);live.setAttribute('aria-live',r?'off':'polite');w.classList.toggle('is-paused',userPaused);pb.setAttribute('aria-label',userPaused?'Slideshow afspelen':'Slideshow pauzeren');}
pb.addEventListener('click',function(){userPaused=!userPaused;sync();});
w.querySelector('.hss__prev').addEventListener('click',function(){show(i-1);sync();});
w.querySelector('.hss__next').addEventListener('click',function(){show(i+1);sync();});
w.addEventListener('keydown',function(e){if(e.key==='ArrowLeft'){show(i-1);sync();e.preventDefault();}else if(e.key==='ArrowRight'){show(i+1);sync();e.preventDefault();}});
w.addEventListener('pointerenter',function(e){if(e.pointerType==='mouse'){hover=true;sync();}});
w.addEventListener('pointerleave',function(){hover=false;sync();});
w.addEventListener('focusin',function(){focus=true;sync();});
w.addEventListener('focusout',function(e){if(!w.contains(e.relatedTarget)){focus=false;sync();}});
var sx=null,sy=0;[].forEach.call(w.querySelectorAll('img'),function(im){im.draggable=false;});w.addEventListener('dragstart',function(e){e.preventDefault();});
w.addEventListener('pointerdown',function(e){if(e.target.closest('a,button'))return;sx=e.clientX;sy=e.clientY;});
w.addEventListener('pointerup',function(e){if(sx===null)return;var dx=e.clientX-sx,dy=e.clientY-sy;sx=null;if(Math.abs(dx)>40&&Math.abs(dx)>Math.abs(dy)){show(dx<0?i+1:i-1);sync();}});
w.addEventListener('pointercancel',function(){sx=null;});
document.addEventListener('visibilitychange',sync);
if('IntersectionObserver' in window){new IntersectionObserver(function(es){inView=es[0].isIntersecting;sync();},{threshold:.35}).observe(w);}else{inView=true;}
show(0);sync();
}
init(document.querySelector('.jouw-container'));
More hero styles
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 →


