Contact met vestiging-tabbladen New
Contact form next to tabs per branch with address, phone, opening hours and a map panel; the chosen branch also fills the form. For businesses with several locations.
How to use it
- Paste the HTML where the page sections 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.
<!-- Contact met vestiging-tabbladen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="cvs">
<div class="cvs__in">
<form class="cvs__form" novalidate>
<span class="cvs__eye">Autobedrijf Brink · contact</span>
<h2 class="cvs__h">Afspraak voor onderhoud of APK?</h2>
<div class="cvs__row"><label class="cvs__f"><span>Naam</span><input name="naam" required autocomplete="name"></label><label class="cvs__f"><span>Telefoon</span><input name="tel" type="tel" required autocomplete="tel"></label></div>
<div class="cvs__row"><label class="cvs__f"><span>Kenteken</span><input name="kenteken" placeholder="bv. 12-ABC-3" autocomplete="off"></label><label class="cvs__f"><span>Vestiging</span><select name="vestiging"><option value="0">Amersfoort</option><option value="1">Ede</option><option value="2">Zwolle</option></select></label></div>
<label class="cvs__f"><span>Waar gaat het om?</span><textarea name="bericht" rows="3" placeholder="bv. APK en grote beurt, liefst op een woensdag"></textarea></label>
<button class="cvs__send" type="submit">Verstuur aanvraag</button>
<p class="cvs__ok" role="status"></p>
</form>
<div class="cvs__loc">
<div class="cvs__tabs" role="tablist" aria-label="Vestigingen">
<button role="tab" class="cvs__tab" aria-selected="true" data-i="0">Amersfoort</button>
<button role="tab" class="cvs__tab" aria-selected="false" tabindex="-1" data-i="1">Ede</button>
<button role="tab" class="cvs__tab" aria-selected="false" tabindex="-1" data-i="2">Zwolle</button>
</div>
<div class="cvs__panel" role="tabpanel">
<div class="cvs__map" aria-hidden="true"><span class="cvs__pin"></span><span class="cvs__lbl"></span></div>
<div class="cvs__info">
<div><span class="cvs__k">Adres</span><p class="cvs__addr"></p></div>
<div><span class="cvs__k">Telefoon</span><p><a class="cvs__tel" href="#"></a></p></div>
<div class="cvs__hours"><span class="cvs__k">Openingstijden</span><dl></dl></div>
</div>
</div>
</div>
</div>
</div>
</div>/* Contact met vestiging-tabbladen · NedDev · eigen werk. */
.cvs{background:#f2f2f0;color:#1c1d1f;font-family:'Switzer',sans-serif;box-sizing:border-box}
.cvs *{box-sizing:border-box}
.cvs__in{max-width:1180px;margin:0 auto;padding:40px 32px;display:grid;grid-template-columns:1fr 1.1fr;gap:36px;align-items:start}
.cvs__eye{font:500 11px 'JetBrains Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#d62828}
.cvs__h{font-size:clamp(22px,2.6vw,32px);font-weight:800;letter-spacing:-.02em;line-height:1.1;margin:8px 0 20px}
.cvs__row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.cvs__f{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.cvs__f span{font-size:12.5px;font-weight:600;color:#45474b}
.cvs__f input,.cvs__f select,.cvs__f textarea{font:400 15px 'Switzer',sans-serif;color:#1c1d1f;background:#fff;border:1px solid #c9cacc;border-radius:3px;padding:10px 12px;width:100%;resize:vertical}
.cvs__f input:focus,.cvs__f select:focus,.cvs__f textarea:focus{outline:2px solid #1c1d1f;outline-offset:-1px;border-color:#1c1d1f}
.cvs__f .is-bad{border-color:#d62828;background:#fff5f5}
.cvs__send{font:700 15px 'Switzer',sans-serif;background:#d62828;color:#fff;border:0;border-radius:3px;padding:13px 22px;cursor:pointer;transition:background .2s}
.cvs__send:hover{background:#1c1d1f}
.cvs__send:focus-visible{outline:2px solid #1c1d1f;outline-offset:2px}
.cvs__ok{font-size:14px;margin:10px 0 0;min-height:20px;color:#1d7a46;font-weight:600}
.cvs__ok.is-err{color:#d62828}
.cvs__loc{background:#1c1d1f;color:#f2f2f0;border-radius:6px;overflow:hidden}
.cvs__tabs{display:flex;border-bottom:1px solid rgba(255,255,255,.12)}
.cvs__tab{flex:1;font:600 14px 'Switzer',sans-serif;color:rgba(242,242,240,.6);background:none;border:0;padding:15px 10px;cursor:pointer;position:relative;transition:color .2s}
.cvs__tab::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:3px;background:#d62828;transform:scaleX(0);transition:transform .25s}
.cvs__tab[aria-selected="true"]{color:#fff}.cvs__tab[aria-selected="true"]::after{transform:none}
.cvs__tab:hover{color:#fff}
.cvs__tab:focus-visible{outline:2px solid #fff;outline-offset:-4px}
.cvs__panel{padding:18px}
.cvs__map{height:150px;border-radius:3px;position:relative;background-color:#2b2d31;background-image:linear-gradient(var(--a1,20deg),transparent 46%,#4a4d53 46% 54%,transparent 54%),linear-gradient(var(--a2,105deg),transparent 47%,#3c3f44 47% 53%,transparent 53%),linear-gradient(0deg,rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:100% 100%,100% 100%,22px 22px,22px 22px;transition:background-position .4s}
.cvs__pin{position:absolute;left:var(--px,50%);top:var(--py,50%);width:22px;height:22px;margin:-22px 0 0 -11px;background:#d62828;border-radius:50% 50% 50% 0;transform:rotate(-45deg);transition:left .45s cubic-bezier(.2,.8,.2,1),top .45s cubic-bezier(.2,.8,.2,1)}
.cvs__pin::after{content:'';position:absolute;inset:7px;border-radius:50%;background:#1c1d1f}
.cvs__lbl{position:absolute;left:12px;bottom:10px;font:500 11px 'JetBrains Mono',monospace;color:rgba(255,255,255,.7)}
.cvs__info{display:grid;grid-template-columns:1fr 1fr;gap:14px 20px;margin-top:16px}
.cvs__hours{grid-column:1/-1}
.cvs__k{font:500 10.5px 'JetBrains Mono',monospace;letter-spacing:.12em;text-transform:uppercase;color:rgba(242,242,240,.5)}
.cvs__info p{margin:5px 0 0;font-size:15px;line-height:1.45}
.cvs__tel{color:#fff;font-weight:700;text-decoration:none;border-bottom:2px solid #d62828}
.cvs__tel:hover{color:#ff8a8a}
.cvs__hours dl{display:grid;grid-template-columns:auto 1fr;gap:3px 16px;margin:6px 0 0;font-size:13.5px}
.cvs__hours dt{color:rgba(242,242,240,.6)}.cvs__hours dd{margin:0}
.cvs__hours .is-today{color:#fff;font-weight:700}
@media(max-width:820px){.cvs__in{grid-template-columns:1fr;padding:28px 16px;gap:24px}.cvs__map{height:120px}}
@media(max-width:420px){.cvs__row{grid-template-columns:1fr;gap:0}.cvs__info{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){.cvs__pin,.cvs__tab::after{transition:none}}// Contact met vestiging-tabbladen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.cvs');if(!w)return;
var V=[
{a:'Ruimtehoek 12<br>3824 MP Amersfoort',t:'033 123 4410',h:[['Ma t/m vr','07:30 tot 17:30'],['Zaterdag','08:30 tot 13:00'],['Zondag','gesloten']],px:'62%',py:'44%',a1:'24deg',a2:'112deg',l:'Bedrijventerrein De Isselt'},
{a:'Proosdijweg 7<br>6716 BX Ede',t:'0318 123 456',h:[['Ma t/m vr','08:00 tot 17:30'],['Zaterdag','gesloten'],['Zondag','gesloten']],px:'34%',py:'58%',a1:'-12deg',a2:'78deg',l:'Naast de Keuringshal'},
{a:'Marsweg 41<br>8013 PE Zwolle',t:'038 123 4477',h:[['Ma t/m vr','07:30 tot 18:00'],['Zaterdag','09:00 tot 14:00'],['Zondag','gesloten']],px:'48%',py:'36%',a1:'48deg',a2:'140deg',l:'Afslag 19 Zwolle-Noord'}];
var tabs=w.querySelectorAll('.cvs__tab'),map=w.querySelector('.cvs__map'),sel=w.querySelector('select[name=vestiging]');
var day=new Date().getDay();var ti=day===0?2:day===6?1:0;
function show(i,focus){var v=V[i];tabs.forEach(function(t,j){var on=j===i;t.setAttribute('aria-selected',on?'true':'false');t.tabIndex=on?0:-1;if(on&&focus)t.focus();});
w.querySelector('.cvs__addr').innerHTML=v.a;var tel=w.querySelector('.cvs__tel');tel.textContent=v.t;tel.href='tel:+31'+v.t.replace(/\s/g,'').slice(1);
w.querySelector('.cvs__hours dl').innerHTML=v.h.map(function(r,j){var c=j===ti?' class="is-today"':'';return '<dt'+c+'>'+r[0]+'</dt><dd'+c+'>'+r[1]+'</dd>';}).join('');
map.style.setProperty('--px',v.px);map.style.setProperty('--py',v.py);map.style.setProperty('--a1',v.a1);map.style.setProperty('--a2',v.a2);w.querySelector('.cvs__lbl').textContent=v.l;sel.value=String(i);}
tabs.forEach(function(t,i){t.addEventListener('click',function(){show(i);});t.addEventListener('keydown',function(e){var n=e.key==='ArrowRight'?1:e.key==='ArrowLeft'?-1:0;if(n){e.preventDefault();show((i+n+3)%3,true);}});});
sel.addEventListener('change',function(){show(+sel.value);});
var f=w.querySelector('.cvs__form'),ok=w.querySelector('.cvs__ok');
f.addEventListener('submit',function(e){e.preventDefault();var bad=[];['naam','tel'].forEach(function(n){var el=f.elements[n];var v=el.value.trim();var good=n==='tel'?v.replace(/\D/g,'').length>=10:v.length>1;el.classList.toggle('is-bad',!good);if(!good)bad.push(el);});
if(bad.length){ok.classList.add('is-err');ok.textContent='Vul je naam en een telefoonnummer van 10 cijfers in.';bad[0].focus();return;}
var vi=+sel.value;ok.classList.remove('is-err');ok.textContent='Dank je, '+f.elements.naam.value.trim().split(' ')[0]+'. We bellen je vandaag nog terug vanuit '+tabs[vi].textContent+'.';f.reset();sel.value=String(vi);});
show(0);
}
init(document.querySelector('.jouw-container'));
More page sections
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 →