Personenteller met bump New
A plus/minus counter where the number rolls in the direction of the click, the field gives a short bump (and the phone vibrates) and shakes with a hint at the limit. For reservations and order quantities.
Reserveren · Bistro Kademuur, Alkmaar
Aantal personenZa 18 okt · 19:00
2
Groepen vanaf 9 personen: bel 072 123 4567
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.
<!-- Personenteller met bump · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="gsb"><div class="gsb__card"><span class="gsb__kk">Reserveren · Bistro Kademuur, Alkmaar</span><div class="gsb__row"><span class="gsb__lb">Aantal personen<small>Za 18 okt · 19:00</small></span>
<div class="gsb__st" role="group" aria-label="Aantal personen"><button class="gsb__b" type="button" data-d="-1" aria-label="Een persoon minder"><svg viewBox="0 0 14 14" width="12" height="12" aria-hidden="true"><path d="M2 7h10" stroke="currentColor" stroke-width="2"/></svg></button><span class="gsb__win" aria-live="polite"><span class="gsb__n">2</span></span><button class="gsb__b" type="button" data-d="1" aria-label="Een persoon meer"><svg viewBox="0 0 14 14" width="12" height="12" aria-hidden="true"><path d="M2 7h10M7 2v10" stroke="currentColor" stroke-width="2"/></svg></button></div></div>
<div class="gsb__seats" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div><p class="gsb__msg">Groepen vanaf 9 personen: bel 072 123 4567</p></div></div>
</div>/* Personenteller met bump · NedDev · eigen werk. */
.gsb{position:absolute;inset:0;background:#f4f3f1;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;display:grid;place-items:center;padding:14px}
.gsb__card{width:min(310px,100%);background:#fff;border-radius:6px;padding:15px 16px;display:flex;flex-direction:column;gap:11px}
.gsb__kk{font:500 9.5px 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#6b6762}
.gsb__row{display:flex;justify-content:space-between;align-items:center;gap:10px}
.gsb__lb{font-size:14px;font-weight:700;letter-spacing:-.01em;display:flex;flex-direction:column}
.gsb__lb small{font:500 10px 'JetBrains Mono',monospace;color:#8a857f;margin-top:2px}
.gsb__st{display:flex;align-items:center;border:1px solid #dcd8d2;border-radius:999px;padding:3px;gap:2px;will-change:transform}
.gsb__b{appearance:none;width:30px;height:30px;border:0;border-radius:50%;background:#f4f3f1;color:#0a0a0a;display:grid;place-items:center;cursor:pointer;transition:background .2s,color .2s,opacity .2s,transform .12s}
.gsb__b:hover{background:#0a0a0a;color:#fff}.gsb__b:active{transform:scale(.88)}.gsb__b:focus-visible{outline:2px solid #F5480F;outline-offset:1px}
.gsb__b.is-lim{opacity:.35}
.gsb__win{position:relative;width:34px;height:30px;overflow:hidden;display:block}
.gsb__n{position:absolute;inset:0;display:grid;place-items:center;font:800 18px 'Switzer',sans-serif;font-variant-numeric:tabular-nums}
.gsb__seats{display:flex;gap:5px}
.gsb__seats i{flex:1;height:6px;border-radius:999px;background:#eeebe7;transition:background .25s,transform .35s cubic-bezier(.3,1.8,.5,1)}
.gsb__seats i.is-on{background:#F5480F}.gsb__seats i.is-pop{transform:scaleY(1.9)}
.gsb__msg{margin:0;font-size:11.5px;color:#57534e;max-height:0;opacity:0;overflow:hidden;transition:max-height .3s,opacity .3s}
.gsb.is-warn .gsb__msg{max-height:2em;opacity:1;color:#c43a0b}
@media (prefers-reduced-motion:reduce){.gsb__seats i,.gsb__msg{transition:none}}// Personenteller met bump · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.gsb')||root;
var st=root.querySelector('.gsb__st'),win=root.querySelector('.gsb__win'),bs=[].slice.call(root.querySelectorAll('.gsb__b')),seats=[].slice.call(root.querySelectorAll('.gsb__seats i'));
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,n=2,MIN=1,MAX=8,touched=false,wt=0;
function seatsUpd(pop){seats.forEach(function(s,i){s.classList.toggle('is-on',i<n);s.classList.remove('is-pop');});if(pop!=null&&seats[pop]){void seats[pop].offsetWidth;seats[pop].classList.add('is-pop');setTimeout(function(){seats[pop].classList.remove('is-pop');},220);}
bs[0].classList.toggle('is-lim',n<=MIN);bs[1].classList.toggle('is-lim',n>=MAX);}
function buzz(ms){if(!touched)return;try{if(navigator.vibrate)navigator.vibrate(ms);}catch(e){}}
function change(d){var to=n+d;if(to<MIN||to>MAX){if(!rm)st.animate([{transform:'none'},{transform:'translateX(-5px)'},{transform:'translateX(4px)'},{transform:'translateX(-3px)'},{transform:'translateX(2px)'},{transform:'none'}],{duration:360,easing:'ease-out'});buzz([12,40,12]);
if(to>MAX){root.classList.add('is-warn');clearTimeout(wt);wt=setTimeout(function(){root.classList.remove('is-warn');},2600);}return;}
var old=win.querySelector('.gsb__n'),nw=document.createElement('span');nw.className='gsb__n';nw.textContent=to;win.appendChild(nw);n=to;
if(!rm){old.animate([{transform:'none',opacity:1},{transform:'translateY('+(-d*100)+'%)',opacity:0}],{duration:300,easing:'cubic-bezier(.7,0,.2,1)'}).onfinish=function(){old.remove();};
nw.animate([{transform:'translateY('+(d*100)+'%)',opacity:0},{transform:'none',opacity:1}],{duration:380,easing:'cubic-bezier(.2,.9,.3,1.2)'});
st.animate([{transform:'scale(1)'},{transform:'scale(1.07)'},{transform:'scale(.985)'},{transform:'scale(1)'}],{duration:340,easing:'ease-out'});}else old.remove();
buzz(8);seatsUpd(d>0?n-1:null);if(n<MAX)root.classList.remove('is-warn');}
bs.forEach(function(b){b.addEventListener('click',function(){touched=true;change(+b.getAttribute('data-d'));});});
st.addEventListener('keydown',function(e){if(e.key==='ArrowUp'||e.key==='ArrowRight'){e.preventDefault();touched=true;change(1);}if(e.key==='ArrowDown'||e.key==='ArrowLeft'){e.preventDefault();touched=true;change(-1);}});
seatsUpd(null);
if(!rm){var seq=[1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1],k=0;(function loop(){setTimeout(function(){if(touched)return;change(seq[k%seq.length]);k++;loop();},k%seq.length===0?900:(k%seq.length===7?1400:520));})();}
}
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 →