Video-modal met facade Nieuw
Bedrijfsfilm als facade: poster, titel, duur en een afspeelknop, zonder YouTube-script of cookies tot iemand klikt. Klik opent een
Laadt pas na klik · geen cookies vooraf
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.
<!-- Video-modal met facade · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="vdm">
<button class="vdm__facade" type="button" aria-haspopup="dialog" aria-label="Speel bedrijfsfilm af: van plank tot keuken, 1 minuut 42">
<img src="https://neddev.com/lab-media/video-modal-1.webp" alt="" width="1000" height="545" loading="lazy">
<span class="vdm__shade" aria-hidden="true"></span>
<span class="vdm__meta" aria-hidden="true"><span class="vdm__tag">Bedrijfsfilm · 1:42</span><span class="vdm__title">Van plank tot keuken: een week in onze werkplaats in Apeldoorn</span></span>
<span class="vdm__play" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg></span>
</button>
<p class="vdm__note">Laadt pas na klik · geen cookies vooraf</p>
<dialog class="vdm__dlg" aria-label="Bedrijfsfilm: van plank tot keuken">
<div class="vdm__frame">
<div class="vdm__film" aria-hidden="true"><span class="vdm__wood"></span><span class="vdm__beam"></span><span class="vdm__demo">Voorbeeldbeeld · hier komt je video</span></div>
<p class="vdm__sub"></p>
<div class="vdm__load" role="status"><span class="vdm__spin" aria-hidden="true"></span><span>Video laden</span></div>
<div class="vdm__ctrl">
<button class="vdm__pp" type="button" aria-label="Pauzeer video"><svg class="vdm__i-pause" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6v12M15 6v12"/></svg><svg class="vdm__i-play" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg></button>
<span class="vdm__time">0:00 / 1:42</span>
<span class="vdm__track" role="progressbar" aria-label="Afgespeeld" aria-valuemin="0" aria-valuemax="102" aria-valuenow="0" aria-valuetext="0 seconden van 1 minuut 42"><span class="vdm__tfill"></span></span>
<button class="vdm__mute" type="button" aria-pressed="false" aria-label="Geluid uit"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9v6h4l5 4V5L8 9z"/><path class="vdm__wave" d="M16.5 8.5a5 5 0 0 1 0 7"/><path class="vdm__xm" d="M16 9.5l5 5M21 9.5l-5 5"/></svg></button>
</div>
<button class="vdm__x" type="button" aria-label="Sluit video"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
</div>
</dialog>
</div>
</div>/* Video-modal met facade · NedDev · eigen werk. */
.vdm{--pop:#F5480F;--pd:#b83a0b;position:absolute;inset:0;font-family:'Switzer',system-ui,sans-serif;color:#fff;background:#0a0a0a;overflow:hidden}
.vdm__facade{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;background:#1b1b1b;cursor:pointer;color:#fff;text-align:left;display:block}
.vdm__facade img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.7,.2,1)}
.vdm__facade:hover img{transform:scale(1.03)}
.vdm__shade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(10,10,10,.82) 0%,rgba(10,10,10,.35) 60%,rgba(10,10,10,.1))}
.vdm__meta{position:absolute;left:18px;bottom:18px;right:90px;display:flex;flex-direction:column;gap:6px}
.vdm__tag{font:600 10px/1 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:#ffd9c9}
.vdm__title{font-size:17px;font-weight:600;line-height:1.25;max-width:24ch}
.vdm__play{position:absolute;right:18px;bottom:18px;width:56px;height:56px;border-radius:50%;background:var(--pop);display:grid;place-items:center;transition:transform .2s ease,background .2s}
.vdm__play svg{width:22px;height:22px;fill:#0a0a0a;margin-left:3px}
.vdm__facade:hover .vdm__play{transform:scale(1.06);background:#ff6a35}
.vdm__facade:active .vdm__play{transform:scale(.97)}
.vdm__facade:focus-visible{outline:3px solid var(--pop);outline-offset:-3px}
.vdm__note{position:absolute;top:12px;left:18px;margin:0;font:600 9.5px/1 'JetBrains Mono',monospace;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.82);pointer-events:none}
.vdm__dlg{position:absolute;inset:0;margin:0;width:100%;height:100%;max-width:none;max-height:none;border:0;padding:0;background:#000;color:#fff;display:grid;place-items:center;opacity:0;transform:scale(.97);transition:opacity .22s ease,transform .22s ease,display .22s allow-discrete,overlay .22s allow-discrete}
.vdm__dlg:not([open]){display:none}
.vdm__dlg[open]{opacity:1;transform:none}
@starting-style{.vdm__dlg[open]{opacity:0;transform:scale(.97)}}
.vdm__frame{position:relative;width:100%;max-height:100%;aspect-ratio:16/9;overflow:hidden;background:#140d08}
.vdm__film{position:absolute;inset:0;overflow:hidden}
.vdm__wood{position:absolute;inset:-20%;background:repeating-linear-gradient(100deg,#6b4423 0 14px,#7a4f2a 14px 22px,#5e3b1e 22px 40px,#83582f 40px 46px);filter:saturate(.9);animation:vdm-pan 14s linear infinite alternate}
.vdm__beam{position:absolute;inset:0;background:radial-gradient(60% 80% at 30% 20%,rgba(255,214,160,.55),rgba(255,214,160,0) 70%),linear-gradient(rgba(0,0,0,0) 55%,rgba(0,0,0,.6));animation:vdm-beam 9s ease-in-out infinite alternate}
.vdm__demo{position:absolute;top:10px;left:12px;font:600 9px/1 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.75);background:rgba(0,0,0,.35);padding:4px 6px;border-radius:2px}
@keyframes vdm-pan{to{transform:translate(8%,-4%) rotate(2deg)}}
@keyframes vdm-beam{to{transform:translateX(18%)}}
.vdm.is-paused .vdm__wood,.vdm.is-paused .vdm__beam,.vdm.is-loading .vdm__wood,.vdm.is-loading .vdm__beam{animation-play-state:paused}
.vdm__sub{position:absolute;left:50%;bottom:48px;transform:translateX(-50%);margin:0;width:max-content;max-width:86%;text-align:center;font-size:13px;line-height:1.35;background:rgba(0,0,0,.65);padding:4px 8px;border-radius:2px}
.vdm__sub:empty{display:none}
.vdm__load{position:absolute;inset:0;display:none;align-items:center;justify-content:center;gap:10px;background:rgba(0,0,0,.55);font-size:13px}
.vdm.is-loading .vdm__load{display:flex}
.vdm__spin{width:20px;height:20px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:vdm-spin .8s linear infinite}
@keyframes vdm-spin{to{transform:rotate(360deg)}}
.vdm__ctrl{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:10px;padding:8px 10px;background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.75))}
.vdm__ctrl button,.vdm__x{width:30px;height:30px;border:0;border-radius:4px;background:rgba(255,255,255,.08);color:#fff;cursor:pointer;display:grid;place-items:center;padding:0;flex:none;transition:background .15s}
.vdm__ctrl button:hover,.vdm__x:hover{background:rgba(255,255,255,.2)}
.vdm__dlg button:focus-visible{outline:2px solid var(--pop);outline-offset:2px}
.vdm__ctrl svg,.vdm__x svg{width:15px;height:15px;fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.vdm__i-play{fill:#fff!important;stroke:none!important;display:none}
.vdm.is-paused .vdm__i-play{display:block}.vdm.is-paused .vdm__i-pause{display:none}
.vdm__xm{display:none}.vdm.is-muted .vdm__xm{display:inline}.vdm.is-muted .vdm__wave{display:none}
.vdm__time{font:600 11px/1 'JetBrains Mono',monospace;font-variant-numeric:tabular-nums;white-space:nowrap}
.vdm__track{flex:1;height:3px;background:rgba(255,255,255,.25);border-radius:2px;overflow:hidden}
.vdm__tfill{display:block;height:100%;width:0;background:var(--pop)}
.vdm__x{position:absolute;top:8px;right:8px;background:rgba(0,0,0,.5)}
@media (max-width:420px){.vdm__title{font-size:14.5px}.vdm__meta{left:14px;bottom:14px;right:80px}.vdm__play{width:48px;height:48px;right:14px;bottom:14px}.vdm__sub{font-size:11.5px;bottom:44px}.vdm__time{font-size:10px}}
@media (prefers-reduced-motion:reduce){.vdm__wood,.vdm__beam{animation:none}.vdm__dlg,.vdm__facade img{transition:none}}// Video-modal met facade · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.vdm');if(!w)return;
var fac=w.querySelector('.vdm__facade'),dlg=w.querySelector('.vdm__dlg'),pp=w.querySelector('.vdm__pp'),mute=w.querySelector('.vdm__mute'),sub=w.querySelector('.vdm__sub'),tm=w.querySelector('.vdm__time'),trk=w.querySelector('.vdm__track'),fill=w.querySelector('.vdm__tfill');
var LEN=102,t=0,tick=0,loadT=0,playing=false;
var SUBS=['Elke keuken begint bij ons als ruwe eikenhouten plank.','In de werkplaats in Apeldoorn zagen en schaven we alles op maat.','Na een week staat hij bij jou thuis, gemonteerd en schoon opgeleverd.'];
function fmt(s){s=Math.floor(s);return Math.floor(s/60)+':'+(s%60<10?'0':'')+(s%60);}
function draw(){tm.textContent=fmt(t)+' / '+fmt(LEN);fill.style.width=(t/LEN*100)+'%';trk.setAttribute('aria-valuenow',Math.floor(t));trk.setAttribute('aria-valuetext',fmt(t)+' van 1:42');sub.textContent=SUBS[Math.floor(t/5)%SUBS.length];}
function setPlay(on){playing=on;w.classList.toggle('is-paused',!on);pp.setAttribute('aria-label',on?'Pauzeer video':'Speel video af');clearInterval(tick);if(on)tick=setInterval(function(){t=(t+1)%LEN;draw();},1000);}
function open(){
// Productie: maak hier pas de iframe aan, bv. frame.innerHTML='<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID?autoplay=1" title="Bedrijfsfilm" allow="autoplay; fullscreen" allowfullscreen></iframe>'
dlg.show();fac.inert=true;w.classList.add('is-loading');sub.textContent='';t=0;draw();sub.textContent='';pp.focus();
loadT=setTimeout(function(){w.classList.remove('is-loading');setPlay(true);draw();},700);}
function close(){clearTimeout(loadT);setPlay(false);w.classList.remove('is-loading','is-paused');dlg.close();fac.inert=false;fac.focus();}
fac.addEventListener('click',open);
w.querySelector('.vdm__x').addEventListener('click',close);
pp.addEventListener('click',function(){if(w.classList.contains('is-loading'))return;setPlay(!playing);});
mute.addEventListener('click',function(){var m=!w.classList.contains('is-muted');w.classList.toggle('is-muted',m);mute.setAttribute('aria-pressed',m);});
dlg.addEventListener('click',function(e){if(e.target===dlg)close();});
dlg.addEventListener('keydown',function(e){if(e.key==='Escape'){e.preventDefault();close();return;}
if(e.key===' '&&e.target===dlg){e.preventDefault();pp.click();}
if(e.key==='Tab'){var f=[pp,mute,w.querySelector('.vdm__x')],a=f[0],z=f[f.length-1];if(e.shiftKey&&document.activeElement===a){e.preventDefault();z.focus();}else if(!e.shiftKey&&document.activeElement===z){e.preventDefault();a.focus();}}});
dlg.addEventListener('cancel',function(e){e.preventDefault();close();});
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
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 →