Afrekenen in drie inklapbare stappen New
Compact one-column checkout: delivery address, shipping and payment as steps that collapse into a summary line with an Edit button once filled in. The postcode is checked and formatted, the shipping choice changes the total that updates live at the bottom, and payment works with iDEAL (bank choice) or credit card. Later steps only open once the previous one is valid. For shops that want checkout in a narrow column or side panel.
-
Bezorgadres
-
Verzending
-
Betalen
Wandelschoenen, maat 42: € 129,95
Verzending € 4,95Totaal € 134,90
Verzending € 4,95Totaal € 134,90
How to use it
- Paste the HTML where the forms & inputs 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.
<!-- Afrekenen in drie inklapbare stappen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="afs"><div class="afs__in">
<ol class="afs__steps">
<li class="afs__st is-open" data-s="adres">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Bezorgadres</h4><p class="afs__sum"></p><button class="afs__edit" type="button" hidden>Wijzig</button></div>
<div class="afs__bd">
<div class="afs__fld"><label class="afs__l" for="afs-n">Naam</label><input class="afs__i afs__n" id="afs-n" autocomplete="name" value="Sanne de Wit"></div>
<div class="afs__two"><div class="afs__fld"><label class="afs__l" for="afs-pc">Postcode</label><input class="afs__i afs__pc" id="afs-pc" autocomplete="postal-code" placeholder="1234 AB" aria-describedby="afs-pce"></div>
<div class="afs__fld"><label class="afs__l" for="afs-hn">Huisnummer</label><input class="afs__i afs__hn" id="afs-hn" inputmode="numeric" autocomplete="address-line2" aria-describedby="afs-pce"></div></div>
<p class="afs__err" id="afs-pce"></p>
<button class="afs__next" type="button">Verder naar verzending</button>
</div></li>
<li class="afs__st" data-s="verz">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Verzending</h4><p class="afs__sum"></p><button class="afs__edit" type="button" hidden>Wijzig</button></div>
<div class="afs__bd" hidden>
<fieldset class="afs__fs"><legend class="afs__vh">Kies een verzendwijze</legend>
<label class="afs__opt"><input type="radio" name="afs-v" value="4.95" data-t="Morgen bezorgd door PostNL" checked><span class="afs__ot">Morgen bezorgd, PostNL</span><span class="afs__op">€ 4,95</span></label>
<label class="afs__opt"><input type="radio" name="afs-v" value="6.95" data-t="Avondlevering 18:00 tot 22:00"><span class="afs__ot">Avond, 18:00 tot 22:00</span><span class="afs__op">€ 6,95</span></label>
<label class="afs__opt"><input type="radio" name="afs-v" value="0" data-t="Ophalen Oudegracht 112, Utrecht"><span class="afs__ot">Ophalen in de winkel, Utrecht</span><span class="afs__op">Gratis</span></label>
</fieldset>
<button class="afs__next" type="button">Verder naar betalen</button>
</div></li>
<li class="afs__st" data-s="bet">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Betalen</h4><p class="afs__sum"></p></div>
<div class="afs__bd" hidden>
<fieldset class="afs__fs"><legend class="afs__vh">Kies een betaalmethode</legend>
<label class="afs__opt"><input type="radio" name="afs-b" value="ideal" checked><span class="afs__ot">iDEAL</span></label>
<div class="afs__sub afs__sub--ideal"><label class="afs__l" for="afs-bank">Je bank</label><select class="afs__i afs__bank" id="afs-bank" aria-describedby="afs-be"><option value="">Kies je bank</option><option>ABN AMRO</option><option>ASN Bank</option><option>bunq</option><option>ING</option><option>Rabobank</option><option>SNS</option><option>Triodos Bank</option></select></div>
<label class="afs__opt"><input type="radio" name="afs-b" value="kaart"><span class="afs__ot">Creditcard</span></label>
<div class="afs__sub afs__sub--kaart" hidden><label class="afs__l" for="afs-cc">Kaartnummer</label><input class="afs__i afs__cc" id="afs-cc" inputmode="numeric" autocomplete="cc-number" placeholder="1234 5678 9012 3456" aria-describedby="afs-be"></div>
</fieldset>
<p class="afs__err" id="afs-be"></p>
<button class="afs__next afs__pay" type="button">Betalen</button>
</div></li>
</ol>
<div class="afs__tot"><span>Wandelschoenen, maat 42: € 129,95<br><span class="afs__vz">Verzending € 4,95</span></span><strong class="afs__sumtot" aria-live="polite">Totaal € 134,90</strong></div>
</div></div>
</div>/* Afrekenen in drie inklapbare stappen · NedDev · eigen werk. */
.afs{position:absolute;inset:0;overflow:auto;display:flex;padding:12px;box-sizing:border-box;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.afs *,.afs *::before,.afs *::after{box-sizing:border-box}
.afs [hidden]{display:none!important}
.afs__in{margin:auto;width:100%;max-width:380px;background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:8px;overflow:hidden}
.afs__steps{list-style:none;margin:0;padding:0}
.afs__st{border-bottom:1px solid rgba(10,10,10,.1);padding:10px 14px}
.afs__hd{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.afs__h{margin:0;font-size:14px;font-weight:700;outline:none;color:#6b6b6b}
.afs__st.is-open .afs__h,.afs__st.is-done .afs__h{color:#0a0a0a}
.afs__st.is-done .afs__h::before{content:'';display:inline-block;width:8px;height:8px;margin-right:7px;background:#1F7A3D;border-radius:2px;vertical-align:1px}
.afs__sum{margin:0;flex:1 1 140px;min-width:0;font-size:12.5px;color:#4a4a4a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.afs__edit{margin-left:auto;border:0;background:none;min-height:24px;padding:2px 0;font:500 12.5px 'Switzer',sans-serif;color:#0a0a0a;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.afs__bd{padding-top:8px;animation:afs-in .22s ease}
@keyframes afs-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.afs__fld{margin-bottom:7px;min-width:0}
.afs__two{display:grid;grid-template-columns:1.3fr 1fr;gap:8px}
.afs__l{display:block;font-size:12.5px;font-weight:600;margin-bottom:3px}
.afs__i{display:block;width:100%;height:34px;padding:0 9px;font:400 14px 'Switzer',sans-serif;color:#0a0a0a;background:#fff;border:1px solid #8c8c8c;border-radius:4px;transition:border-color .15s,box-shadow .15s}
.afs__i:hover{border-color:#0a0a0a}
.afs__i:focus-visible{outline:none;border-color:#0a0a0a;box-shadow:0 0 0 3px rgba(245,72,15,.35)}
.afs__i[aria-invalid="true"]{border-color:#B42318}
.afs__err{margin:0 0 6px;font-size:12.5px;color:#B42318}
.afs__err:empty{display:none}
.afs__fs{border:0;margin:0 0 6px;padding:0;min-width:0;display:grid;gap:5px}
.afs__vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;padding:0}
.afs__opt{position:relative;display:flex;align-items:center;gap:9px;min-height:36px;padding:6px 10px;border:1px solid rgba(10,10,10,.2);border-radius:4px;font-size:13px;cursor:pointer;transition:border-color .15s,background-color .15s}
.afs__opt:hover{border-color:#0a0a0a}
.afs__opt:has(input:checked){border-color:#0a0a0a;box-shadow:inset 0 0 0 1px #0a0a0a;background:#faf9f7}
.afs__opt input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.afs__opt::before{content:'';flex:none;width:16px;height:16px;border:1.5px solid #6b6b6b;border-radius:50%;background:#fff}
.afs__opt:has(input:checked)::before{border-color:#0a0a0a;box-shadow:inset 0 0 0 4px #fff;background:#0a0a0a}
.afs__opt:has(input:focus-visible){outline:2px solid #F5480F;outline-offset:2px}
.afs__ot{flex:1}
.afs__op{font-weight:600}
.afs__sub{padding:2px 0 4px 26px}
.afs__next{height:36px;padding:0 14px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 13.5px 'Switzer',sans-serif;cursor:pointer;transition:background-color .15s}
.afs__next:hover{background:#2a2a2a}
.afs__next:active{transform:translateY(1px)}
.afs__pay{background:#F5480F;color:#0a0a0a;width:100%}
.afs__pay:hover{background:#ff6a36}
.afs__next:focus-visible,.afs__edit:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.afs__pay:focus-visible{outline-color:#0a0a0a}
.afs__tot{display:flex;justify-content:space-between;align-items:flex-end;gap:10px;padding:10px 14px;background:#f4f3f1;font-size:12.5px;color:#4a4a4a;line-height:1.4}
.afs__sumtot{font-size:14px;color:#0a0a0a;white-space:nowrap}
.afs__paid{margin:0;padding:4px 0;font-size:13px;line-height:1.4}
@media (prefers-reduced-motion:reduce){.afs *{transition:none!important;animation:none!important}}// Afrekenen in drie inklapbare stappen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.afs');if(!w)return;
var sfx='-'+Math.random().toString(36).slice(2,7);
w.querySelectorAll('[id]').forEach(function(el){el.id=el.id+sfx;});
w.querySelectorAll('[for]').forEach(function(el){el.setAttribute('for',el.getAttribute('for')+sfx);});
w.querySelectorAll('[aria-describedby]').forEach(function(el){el.setAttribute('aria-describedby',el.getAttribute('aria-describedby')+sfx);});
w.querySelectorAll('input[type=radio]').forEach(function(r){r.name=r.name+sfx;});
var steps=[].slice.call(w.querySelectorAll('.afs__st')),SUB=129.95,ship=4.95;
var CITY={'10':'Amsterdam','25':'Den Haag','30':'Rotterdam','35':'Utrecht','56':'Eindhoven','97':'Groningen','80':'Zwolle','65':'Nijmegen'};
function eur(n){return '\u20ac\u00a0'+n.toFixed(2).replace('.',',');}
function tot(){w.querySelector('.afs__vz').textContent=ship?'Verzending '+eur(ship):'Verzending gratis';var t='Totaal '+eur(SUB+ship);w.querySelector('.afs__sumtot').textContent=t;w.querySelector('.afs__pay').textContent='Betaal '+eur(SUB+ship);}
function open(i){steps.forEach(function(s,k){var bd=s.querySelector('.afs__bd'),ed=s.querySelector('.afs__edit');bd.hidden=k!==i;s.classList.toggle('is-open',k===i);if(ed)ed.hidden=!(s.classList.contains('is-done')&&k!==i);s.querySelector('.afs__sum').hidden=k===i;});
var h=steps[i].querySelector('.afs__h');h.focus();}
function done(i,txt){var s=steps[i];s.classList.add('is-done');s.querySelector('.afs__sum').textContent=txt;}
var pc=w.querySelector('.afs__pc'),hn=w.querySelector('.afs__hn'),nm=w.querySelector('.afs__n'),pce=w.querySelector('[id^="afs-pce"]');
pc.addEventListener('blur',function(){var v=pc.value.replace(/\s/g,'').toUpperCase();if(/^[1-9]\d{3}[A-Z]{2}$/.test(v))pc.value=v.slice(0,4)+' '+v.slice(4);});
steps[0].querySelector('.afs__next').addEventListener('click',function(){var v=pc.value.replace(/\s/g,'').toUpperCase(),m='';
pc.removeAttribute('aria-invalid');hn.removeAttribute('aria-invalid');
if(!/^[1-9]\d{3}[A-Z]{2}$/.test(v)){m='Vul een postcode in zoals 3511 AB';pc.setAttribute('aria-invalid','true');}
else if(!/^\d+\s?[a-zA-Z]?$/.test(hn.value.trim())){m='Vul je huisnummer in, eventueel met toevoeging zoals 12a';hn.setAttribute('aria-invalid','true');}
pce.textContent=m;if(m){(pc.getAttribute('aria-invalid')?pc:hn).focus();return;}
pc.value=v.slice(0,4)+' '+v.slice(4);var c=CITY[v.slice(0,2)];
done(0,(nm.value.trim()||'Geen naam')+', '+pc.value+' '+hn.value.trim()+(c?', '+c:''));open(1);});
w.querySelectorAll('input[name^="afs-v"]').forEach(function(r){r.addEventListener('change',function(){ship=parseFloat(r.value);tot();});});
steps[1].querySelector('.afs__next').addEventListener('click',function(){var r=w.querySelector('input[name^="afs-v"]:checked');done(1,r.getAttribute('data-t')+(ship?', '+eur(ship):''));open(2);});
var subI=w.querySelector('.afs__sub--ideal'),subK=w.querySelector('.afs__sub--kaart'),bank=w.querySelector('.afs__bank'),cc=w.querySelector('.afs__cc'),be=w.querySelector('[id^="afs-be"]');
w.querySelectorAll('input[name^="afs-b"]').forEach(function(r){r.addEventListener('change',function(){subI.hidden=r.value!=='ideal';subK.hidden=r.value!=='kaart';be.textContent='';});});
cc.addEventListener('input',function(){var d=cc.value.replace(/\D/g,'').slice(0,19);cc.value=d.replace(/(\d{4})(?=\d)/g,'$1 ');});
steps.forEach(function(s,i){var ed=s.querySelector('.afs__edit');if(ed)ed.addEventListener('click',function(){open(i);});});
w.querySelector('.afs__pay').addEventListener('click',function(){var m=w.querySelector('input[name^="afs-b"]:checked').value,err='';
bank.removeAttribute('aria-invalid');cc.removeAttribute('aria-invalid');
if(m==='ideal'&&!bank.value){err='Kies je bank om met iDEAL te betalen';bank.setAttribute('aria-invalid','true');}
if(m==='kaart'&&cc.value.replace(/\D/g,'').length<15){err='Vul het volledige kaartnummer in';cc.setAttribute('aria-invalid','true');}
be.textContent=err;if(err){(m==='ideal'?bank:cc).focus();return;}
var b=w.querySelector('.afs__pay');b.textContent=m==='ideal'?'Je gaat naar '+bank.value:'Bezig met betalen';b.disabled=true;
setTimeout(function(){var bd=steps[2].querySelector('.afs__bd');done(2,m==='ideal'?'iDEAL, '+bank.value:'Creditcard, eindigend op '+cc.value.replace(/\D/g,'').slice(-4));
bd.innerHTML='<p class="afs__paid" role="status">Betaald. Bestelnummer 40712, de bevestiging staat in je mail.</p>';steps.forEach(function(s){var e=s.querySelector('.afs__edit');if(e)e.hidden=true;s.querySelector('.afs__sum').hidden=false;});},900);});
tot();open(0);w.querySelector('.afs__h').blur();
}
init(document.querySelector('.jouw-container'));
More forms & inputs
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 →