Envelop opent en de uitnodiging schuift eruit Nieuw
Een gesloten envelop met zegel: scrollen klapt de klep open, de uitnodiging schuift eruit en komt groot in beeld, met een knop die een agendabestand (.ics) geeft. Voor de bedankpagina na een aanmelding, een uitnodiging voor een open dag of een jubileumfeest. Eigen scrollvak met toetsenbord; de knop is pas bereikbaar als de brief eruit is, en bij minder beweging klapt de klep niet maar vervaagt hij.
Welkom op onze open dag
Zaterdag 14 november, 10:00 tot 13:00
De Vlinder, Kerkstraat 8, Amersfoort
Rondleiding om 10:30 en 11:30. Kinderen zijn welkom, aanmelden hoeft niet.
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.
<!-- Envelop opent en de uitnodiging schuift eruit · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="ev">
<div class="ev__vak" tabindex="0" role="region" aria-label="Uitnodiging voor de open dag. Scroll in dit vak om de envelop te openen.">
<div class="ev__baan">
<div class="ev__beeld">
<div class="ev__env">
<div class="ev__achter"></div>
<div class="ev__brief" inert>
<h3 class="ev__kop">Welkom op onze open dag</h3>
<p class="ev__p">Zaterdag 14 november, 10:00 tot 13:00<br>De Vlinder, Kerkstraat 8, Amersfoort</p>
<p class="ev__p ev__p--klein">Rondleiding om 10:30 en 11:30. Kinderen zijn welkom, aanmelden hoeft niet.</p>
<button type="button" class="ev__knop">Zet in mijn agenda</button>
</div>
<div class="ev__voor"></div>
<div class="ev__klep"><span class="ev__zegel" aria-hidden="true">V</span></div>
</div>
</div>
</div>
</div>
<p class="ev__hint" aria-hidden="true">Scroll om te openen</p>
</div>
</div>/* Envelop opent en de uitnodiging schuift eruit · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.ev{position:absolute;inset:0;container-type:size;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;background:#f4f3f1}
.ev__vak{position:absolute;inset:0;overflow-y:auto;scrollbar-width:none}
.ev__vak::-webkit-scrollbar{display:none}
.ev__vak:focus-visible{outline:2px solid #F5480F;outline-offset:-2px}
.ev__baan{height:500cqh}
.ev__beeld{position:sticky;top:0;height:100cqh;overflow:hidden}
.ev__env{position:absolute;left:50%;top:0;width:min(70cqw,118cqh);aspect-ratio:1.55;perspective:600px;transform:translateX(-50%)}
.ev__achter{position:absolute;inset:0;background:#c63a0c;border-radius:4px}
.ev__brief{position:absolute;left:4%;top:6%;width:92%;height:88%;box-sizing:border-box;display:flex;flex-direction:column;align-items:flex-start;background:#fff;border-radius:4px;padding:10px 12px;overflow:hidden;z-index:2;box-shadow:0 1px 3px rgba(10,10,10,.18)}
.ev__kop{font-size:clamp(14px,4.4cqw,18px);font-weight:700;line-height:1.15;margin:0 0 6px}
.ev__p{font-size:12px;line-height:1.4;margin:0 0 8px;color:#333}
.ev__p--klein{color:#5b5b5b}
@container (max-width:380px){.ev__p--klein{display:none}}
.ev__knop{margin-top:auto;flex:none;font:600 12px 'Switzer',system-ui,sans-serif;min-height:28px;padding:5px 10px;border:0;border-radius:4px;background:#F5480F;color:#0a0a0a;cursor:pointer}
.ev__knop:hover{background:#0a0a0a;color:#fff}
.ev__knop:focus-visible{outline:2px solid #0a0a0a;outline-offset:2px}
.ev__voor{position:absolute;inset:0;z-index:3;background:#F5480F;border-radius:4px;clip-path:polygon(0 0,50% 54%,100% 0,100% 100%,0 100%)}
.ev__klep{position:absolute;left:0;top:0;width:100%;height:58%;z-index:4;transform-origin:50% 0;background:#e0400b;clip-path:polygon(0 0,100% 0,50% 100%)}
.ev__klep.is-open{z-index:1;background:#0a0a0a}
.ev__zegel{position:absolute;left:50%;bottom:6%;width:22px;height:22px;margin-left:-11px;border-radius:50%;background:#0a0a0a;color:#F5480F;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center}
.ev__klep.is-open .ev__zegel{opacity:0}
.ev__hint{position:absolute;right:10px;top:8px;margin:0;font-size:12px;background:#fff;padding:3px 8px;border-radius:4px;pointer-events:none;transition:opacity .3s}
.ev.is-weg .ev__hint{opacity:0}// Envelop opent en de uitnodiging schuift eruit · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie
// root = het element waarin de HTML staat
function init(root){
const w = root.querySelector('.ev'); if (!w) return;
const vak = w.querySelector('.ev__vak'), env = w.querySelector('.ev__env'), brief = w.querySelector('.ev__brief'), klep = w.querySelector('.ev__klep'), knop = w.querySelector('.ev__knop');
const rm = matchMedia('(prefers-reduced-motion: reduce)').matches;
const cl = v => v < 0 ? 0 : v > 1 ? 1 : v, ease = t => t < .5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
let raf = 0;
function teken() {
raf = 0; const m = vak.scrollHeight - vak.clientHeight, p = m > 0 ? vak.scrollTop / m : 0;
const H = vak.clientHeight, eH = env.offsetHeight, bH = brief.offsetHeight;
const a = ease(cl(p / .3)), b = ease(cl((p - .32) / .5));
const top0 = (H - eH) / 2, opstijg = bH + eH * .06 + 6, top1 = (H - bH) / 2 - eH * .06 + opstijg;
env.style.transform = 'translate(-50%,' + (top0 + (top1 - top0) * b).toFixed(1) + 'px)';
brief.style.transform = 'translateY(' + (-opstijg * b).toFixed(1) + 'px)';
if (rm) { klep.style.opacity = 1 - a; klep.classList.toggle('is-open', a > .5); }
else { klep.style.transform = 'rotateX(' + (a * 178).toFixed(1) + 'deg)'; klep.classList.toggle('is-open', a > .5); }
const klaar = p > .84; brief.inert = !klaar; brief.style.zIndex = b > 0 ? 5 : 2;
w.classList.toggle('is-weg', vak.scrollTop > 8);
}
knop.addEventListener('click', () => {
const ics = ['BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//De Vlinder//Open dag//NL', 'BEGIN:VEVENT', 'UID:opendag-2026@voorbeeld.nl', 'DTSTAMP:20261020T090000Z', 'DTSTART:20261114T090000Z', 'DTEND:20261114T120000Z', 'SUMMARY:Open dag De Vlinder', 'LOCATION:Kerkstraat 8\\, Amersfoort', 'END:VEVENT', 'END:VCALENDAR'].join('\r\n');
const a = document.createElement('a'); a.href = URL.createObjectURL(new Blob([ics], { type: 'text/calendar' })); a.download = 'open-dag-de-vlinder.ics';
document.body.appendChild(a); a.click(); a.remove(); setTimeout(() => URL.revokeObjectURL(a.href), 1000);
knop.textContent = 'Agendabestand gedownload';
});
vak.addEventListener('scroll', () => { if (!raf) raf = requestAnimationFrame(teken); }, { passive: true });
if (window.ResizeObserver) new ResizeObserver(() => teken()).observe(vak);
teken();
}
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 →