Hero met boekbalk als onderrand Nieuw
Fotohero voor evenementenlocatie of hotel met een boekbalk over de onderrand: datumbereik, aantal gasten en soort evenement. Toont laden, fout (einddatum vóór begindatum), leeg (te veel gasten) en resultaat met vrije zalen. Native date-inputs, geen datepicker-library; in productie koppel je de zoekactie aan je reserveringssysteem.
Remise Oost · Zaandam · 3 zalen tot 650 gasten
Een zaal aan de Zaan voor uw jubileum, congres of personeelsfeest.
Voormalige tramremise uit 1911, 12 minuten van Amsterdam Centraal. Eigen keuken, gratis parkeren voor 140 auto’s.
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.
<!-- Hero met boekbalk als onderrand · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="bbh">
<div class="bbh__hero">
<img class="bbh__img" src="https://neddev.com/lab-media/boekbalk-hero-rand-1.webp" alt="Ketelhuis van Remise Oost, gedekt voor een diner met lange tafels" loading="lazy">
<div class="bbh__copy">
<p class="bbh__eyebrow">Remise Oost · Zaandam · 3 zalen tot 650 gasten</p>
<h2 class="bbh__h">Een zaal aan de Zaan voor uw jubileum, congres of personeelsfeest.</h2>
<p class="bbh__lead">Voormalige tramremise uit 1911, 12 minuten van Amsterdam Centraal. Eigen keuken, gratis parkeren voor 140 auto’s.</p>
</div>
</div>
<form class="bbh__bar" novalidate aria-label="Beschikbaarheid zoeken">
<div class="bbh__f bbh__f--date"><label for="bbh-van">Van</label><input id="bbh-van" class="bbh__in" type="date" value="2026-11-13" min="2026-10-07" required></div>
<div class="bbh__f bbh__f--date"><label for="bbh-tot">Tot en met</label><input id="bbh-tot" class="bbh__in" type="date" value="2026-11-13" min="2026-10-07" required aria-describedby="bbh-err"></div>
<div class="bbh__f"><label for="bbh-n">Gasten</label>
<div class="bbh__step"><button type="button" class="bbh__sb" data-d="-10" aria-label="10 gasten minder">-</button><input id="bbh-n" class="bbh__in bbh__num" type="number" inputmode="numeric" min="10" max="2000" step="10" value="120"><button type="button" class="bbh__sb" data-d="10" aria-label="10 gasten meer">+</button></div>
</div>
<div class="bbh__f"><label for="bbh-soort">Soort</label>
<select id="bbh-soort" class="bbh__in"><option>Diner</option><option>Congres</option><option>Feest</option><option>Vergadering</option></select>
</div>
<button type="submit" class="bbh__go"><span class="bbh__spin" aria-hidden="true"></span><span class="bbh__go-lbl">Bekijk vrije zalen</span></button>
<p class="bbh__err" id="bbh-err" role="alert"></p>
</form>
<div class="bbh__out" aria-live="polite">
<p class="bbh__range"></p>
<div class="bbh__res"></div>
</div>
</div>
</div>/* Hero met boekbalk als onderrand · NedDev · eigen werk. */
/* fonts (Fontshare): boska@400,500 + satoshi@400,500,700 */
.bbh{--ink:#231a15;--mut:#6b5e54;--cream:#f6f1e8;--line:#e0d5c4;--cop:#9e4f20;--cop2:#843f15;background:var(--cream);color:var(--ink);font-family:'Satoshi','Switzer',sans-serif;box-sizing:border-box;padding-bottom:28px}
.bbh *,.bbh *::before{box-sizing:border-box}
.bbh__hero{position:relative;height:440px;overflow:hidden;background:#2a1d17}
.bbh__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 60%}
.bbh__hero::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(25,16,11,.82) 0%,rgba(25,16,11,.5) 48%,rgba(25,16,11,.05) 80%)}
.bbh__copy{position:relative;z-index:1;max-width:1180px;margin:0 auto;padding:58px 40px 0;color:#fff}
.bbh__eyebrow{margin:0 0 14px;font:500 11px/1 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:#f0c9a8}
.bbh__h{margin:0 0 14px;font-family:'Boska',Georgia,serif;font-weight:500;font-size:clamp(30px,4vw,50px);line-height:1.04;max-width:20ch}
.bbh__lead{margin:0;font-size:16px;line-height:1.55;max-width:44ch;color:rgba(255,255,255,.86)}
.bbh__bar{position:relative;z-index:2;max-width:1100px;margin:-62px auto 0;background:#fff;border-radius:6px;box-shadow:0 18px 40px -18px rgba(35,26,21,.45);display:grid;grid-template-columns:1fr 1fr 170px 150px auto;align-items:stretch;padding:8px}
.bbh__f{display:flex;flex-direction:column;justify-content:center;gap:3px;padding:8px 14px;border-right:1px solid var(--line);min-width:0}
.bbh__f label{font:500 10.5px 'JetBrains Mono',monospace;letter-spacing:.1em;text-transform:uppercase;color:var(--mut)}
.bbh__in{width:100%;min-width:0;font:600 16px 'Satoshi',sans-serif;color:var(--ink);background:transparent;border:0;border-radius:3px;padding:4px 2px;outline:none}
.bbh__in:focus-visible{box-shadow:0 0 0 2px var(--cop)}
.bbh__in[aria-invalid="true"]{color:#a2231a;box-shadow:0 0 0 2px #a2231a}
.bbh__step{display:flex;align-items:center;gap:4px}
.bbh__num{text-align:center;-moz-appearance:textfield;font-variant-numeric:tabular-nums}
.bbh__num::-webkit-inner-spin-button,.bbh__num::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.bbh__sb{flex:none;width:28px;height:28px;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--ink);font:600 16px/1 'Satoshi',sans-serif;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}
.bbh__sb:hover{border-color:var(--ink)}
.bbh__sb:active{background:var(--cream)}
.bbh__sb:focus-visible{outline:2px solid var(--cop);outline-offset:2px}
.bbh__go{display:inline-flex;align-items:center;justify-content:center;gap:8px;margin-left:8px;padding:0 24px;border:0;border-radius:4px;background:var(--cop);color:#fff;font:700 15px 'Satoshi',sans-serif;cursor:pointer;white-space:nowrap;transition:background-color .15s ease}
.bbh__go:hover{background:var(--cop2)}
.bbh__go:active{transform:translateY(1px)}
.bbh__go:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
.bbh__go[aria-busy="true"]{cursor:progress;background:#b9805c}
.bbh__spin{display:none;width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:bbh-spin .7s linear infinite}
.bbh__go[aria-busy="true"] .bbh__spin{display:inline-block}
@keyframes bbh-spin{to{transform:rotate(360deg)}}
.bbh__err{grid-column:1/-1;margin:0;font-size:13.5px;color:#a2231a;font-weight:500}
.bbh__err:not(:empty){padding:8px 14px 4px}
.bbh__out{max-width:1100px;margin:16px auto 0;padding:0 8px}
.bbh__range{margin:0 0 10px;font:500 12px 'JetBrains Mono',monospace;letter-spacing:.04em;color:var(--mut)}
.bbh__res{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.bbh__room{background:#fff;border:1px solid var(--line);border-radius:5px;padding:14px 16px;display:flex;flex-direction:column;gap:4px}
.bbh__room b{font-family:'Boska',Georgia,serif;font-weight:500;font-size:20px}
.bbh__room span{font-size:13.5px;color:var(--mut)}
.bbh__room strong{font-size:15px;font-variant-numeric:tabular-nums;margin-top:4px}
.bbh__opt{align-self:flex-start;margin-top:8px;font:700 13.5px 'Satoshi',sans-serif;color:var(--cop);background:transparent;border:1.5px solid var(--cop);border-radius:4px;padding:7px 12px;cursor:pointer;transition:background-color .15s ease,color .15s ease}
.bbh__opt:hover{background:var(--cop);color:#fff}
.bbh__opt:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.bbh__opt[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.bbh__room--off{background:transparent;border-style:dashed}
.bbh__msg{grid-column:1/-1;background:#fff;border:1px dashed var(--line);border-radius:5px;padding:14px 16px;font-size:14.5px;line-height:1.5}
@media (max-width:900px){
.bbh__hero{height:400px}
.bbh__hero::after{background:linear-gradient(180deg,rgba(25,16,11,.78) 0%,rgba(25,16,11,.6) 70%,rgba(25,16,11,.4) 100%)}
.bbh__copy{padding:34px 18px 0}
.bbh__bar{margin:-46px 12px 0;grid-template-columns:1fr 1fr;padding:6px}
.bbh__f{border-right:0;border-bottom:1px solid var(--line);padding:8px 10px}
.bbh__go{grid-column:1/-1;margin:8px 0 2px;padding:14px}
.bbh__out{padding:0 12px}
.bbh__res{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){.bbh *{transition:none!important}.bbh__spin{animation-duration:2s}}// Hero met boekbalk als onderrand · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
const w=root.querySelector('.bbh'); if(!w) return;
const f=w.querySelector('.bbh__bar'), van=w.querySelector('#bbh-van'), tot=w.querySelector('#bbh-tot'), n=w.querySelector('#bbh-n'), soort=w.querySelector('#bbh-soort'), go=w.querySelector('.bbh__go'), lbl=w.querySelector('.bbh__go-lbl'), err=w.querySelector('.bbh__err'), rng=w.querySelector('.bbh__range'), res=w.querySelector('.bbh__res');
const Z=[{n:'Ketelhuis',max:650,p:4950,s:'Hoge kap, eigen bar, podium 8 x 6 m'},{n:'Wagenhal',max:280,p:2450,s:'Daglicht, aan het water, eigen terras'},{n:'Seinhuis',max:60,p:875,s:'Vergaderzaal met scherm en geluid'}];
const BUSY={'2026-11-14':['Ketelhuis'],'2026-11-21':['Ketelhuis','Wagenhal'],'2026-12-12':['Ketelhuis','Wagenhal'],'2026-12-19':['Ketelhuis','Wagenhal','Seinhuis']};
const d=s=>new Date(s+'T12:00');
const fmt=x=>x.toLocaleDateString('nl-NL',{weekday:'short',day:'numeric',month:'short'});
const eur=v=>'€ '+v.toLocaleString('nl-NL',{minimumFractionDigits:2,maximumFractionDigits:2});
const days=()=>Math.round((d(tot.value)-d(van.value))/864e5)+1;
const showRange=()=>{if(!van.value||!tot.value||d(tot.value)<d(van.value)){rng.textContent='';return;} const k=days(); rng.textContent=(k===1?fmt(d(van.value)):fmt(d(van.value))+' t/m '+fmt(d(tot.value)))+' · '+k+(k===1?' dag':' dagen')+' · '+n.value+' gasten';};
const clamp=()=>{let v=parseInt(n.value,10); if(isNaN(v)) v=10; n.value=Math.max(10,Math.min(2000,v));};
w.querySelectorAll('.bbh__sb').forEach(b=>b.addEventListener('click',()=>{n.value=(parseInt(n.value,10)||0)+parseInt(b.dataset.d,10); clamp(); showRange();}));
van.addEventListener('change',()=>{if(van.value&&(!tot.value||d(tot.value)<d(van.value))) tot.value=van.value; tot.min=van.value||tot.min; showRange();});
[tot,n].forEach(x=>x.addEventListener('change',()=>{clamp(); showRange();}));
const setErr=(m,el)=>{err.textContent=m; [van,tot].forEach(x=>x.removeAttribute('aria-invalid')); if(el){el.setAttribute('aria-invalid','true'); el.focus();}};
f.addEventListener('submit',e=>{e.preventDefault(); if(go.getAttribute('aria-busy')==='true') return;
if(!van.value||!tot.value){setErr('Kies een begin- en einddatum.',!van.value?van:tot); return;}
if(d(tot.value)<d(van.value)){setErr('De einddatum ligt vóór de begindatum. Kies een datum vanaf '+fmt(d(van.value))+'.',tot); return;}
setErr(''); clamp(); showRange();
go.setAttribute('aria-busy','true'); lbl.textContent='Zoeken...'; res.innerHTML='';
setTimeout(()=>{go.removeAttribute('aria-busy'); lbl.textContent='Bekijk vrije zalen';
const g=+n.value, k=days(), dates=[]; for(let i=0;i<k;i++){const x=d(van.value); x.setDate(x.getDate()+i); dates.push(x.toISOString().slice(0,10));}
const busy=new Set(dates.flatMap(x=>BUSY[x]||[]));
const fit=Z.filter(z=>z.max>=g);
if(!fit.length){res.innerHTML='<p class="bbh__msg"><b>Geen zaal voor '+g+' gasten.</b> Onze grootste zaal, het Ketelhuis, past tot 650 gasten. Voor grotere evenementen gebruiken we ook het buitenterrein: bel Sanne de Wit op 075 123 45 67.</p>'; return;}
res.innerHTML=fit.map(z=>busy.has(z.n)?'<div class="bbh__room bbh__room--off"><b>'+z.n+'</b><span>Al geboekt op deze datum</span><span>Tot '+z.max+' gasten</span></div>':'<div class="bbh__room"><b>'+z.n+'</b><span>'+z.s+'</span><span>Tot '+z.max+' gasten · '+soort.value.toLowerCase()+'</span><strong>vanaf '+eur(z.p*k)+'</strong><button type="button" class="bbh__opt" aria-pressed="false">Optie nemen</button></div>').join('');
if(fit.every(z=>busy.has(z.n))) res.insertAdjacentHTML('beforeend','<p class="bbh__msg">Alle passende zalen zijn bezet. Probeer de vrijdag ervoor of zet u op de wachtlijst.</p>');
},850);
});
res.addEventListener('click',e=>{const b=e.target.closest('.bbh__opt'); if(!b) return; const on=b.getAttribute('aria-pressed')!=='true'; b.setAttribute('aria-pressed',on?'true':'false'); b.textContent=on?'Optie genomen, 7 dagen geldig':'Optie nemen';});
showRange();
}
init(document.querySelector('.jouw-container'));
Meer uit paginasecties
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 →