Verzendknop met voortgang Nieuw
De knop vult zich tijdens het versturen met een oranje balk en een oplopend percentage, en rolt daarna door naar een bevestiging met vinkje. Voor offerte- en contactformulieren.
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.
<!-- Verzendknop met voortgang · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="spb"><form class="spb__f" novalidate><label class="spb__lb"><span>E-mailadres</span><input class="spb__in" type="email" value="j.devries@voorbeeld.nl" autocomplete="email"></label>
<button class="spb__btn" type="submit"><span class="spb__fill" aria-hidden="true"></span><span class="spb__lbl"><span class="spb__s">Offerte aanvragen <svg viewBox="0 0 16 16" width="13" height="13" aria-hidden="true"><path d="M3 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.8"/></svg></span><span class="spb__s">Versturen <span><b class="spb__pct">0</b>%</span></span><span class="spb__s"><svg class="spb__ck" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M3 8.5l3.2 3L13 4.5" fill="none" stroke="currentColor" stroke-width="2" pathLength="1"/></svg>Verstuurd</span></span></button>
<p class="spb__note" aria-live="polite"></p></form></div>
</div>/* Verzendknop met voortgang · NedDev · eigen werk. */
.spb{position:absolute;inset:0;background:#f4f3f1;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;display:grid;place-items:center;padding:14px}
.spb__f{width:min(300px,100%);background:#fff;border-radius:6px;padding:16px;display:flex;flex-direction:column;gap:10px;box-shadow:0 1px 0 rgba(10,10,10,.06)}
.spb__lb{display:flex;flex-direction:column;gap:5px;font:500 10px 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#6b6762}
.spb__in{font:500 13px 'Switzer',sans-serif;color:#0a0a0a;border:1px solid #dcd8d2;border-radius:4px;padding:9px 10px;outline:none;transition:border-color .2s;text-transform:none;letter-spacing:0}
.spb__in:focus{border-color:#0a0a0a}
.spb__btn{appearance:none;position:relative;height:42px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 13px 'Switzer',sans-serif;cursor:pointer;overflow:hidden;transition:background .35s,transform .15s}
.spb__btn:active{transform:scale(.98)}.spb__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.spb__btn:disabled{cursor:progress}
.spb__fill{position:absolute;left:0;top:0;bottom:0;width:0;background:#F5480F}
.spb__lbl{position:relative;display:block;height:42px;overflow:hidden}
.spb__s{display:flex;align-items:center;justify-content:center;gap:7px;height:42px;transition:transform .45s cubic-bezier(.7,0,.2,1)}
.spb[data-s="1"] .spb__s{transform:translateY(-100%)}.spb[data-s="2"] .spb__s{transform:translateY(-200%)}
.spb__pct{font:700 13px 'JetBrains Mono',monospace;min-width:2.2ch;text-align:right;font-variant-numeric:tabular-nums}
.spb[data-s="2"] .spb__btn{background:#F5480F}.spb[data-s="2"] .spb__fill{opacity:0}
.spb__ck path{stroke-dasharray:1;stroke-dashoffset:1}
.spb[data-s="2"] .spb__ck path{stroke-dashoffset:0;transition:stroke-dashoffset .4s .3s}
.spb__note{margin:0;min-height:1.4em;font-size:11.5px;color:#57534e;opacity:0;transform:translateY(-4px);transition:opacity .3s,transform .3s}
.spb[data-s="2"] .spb__note{opacity:1;transform:none;transition-delay:.35s}
@media (prefers-reduced-motion:reduce){.spb__s,.spb__note{transition:none}}// Verzendknop met voortgang · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.spb')||root;
var f=root.querySelector('.spb__f'),btn=root.querySelector('.spb__btn'),fill=root.querySelector('.spb__fill'),pct=root.querySelector('.spb__pct'),note=root.querySelector('.spb__note');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,busy=false,touched=false,D=1800;
function curve(t){if(t<.45){var u=t/.45;return .7*(1-Math.pow(1-u,2));}if(t<.7)return .7+.06*((t-.45)/.25);var v=(t-.7)/.3;return .76+.24*v*v;}
function run(){if(busy)return;busy=true;btn.disabled=true;root.setAttribute('data-s','1');note.textContent='';var t0=performance.now();
requestAnimationFrame(function step(now){var t=Math.min(1,(now-t0)/(rm?300:D)),p=curve(t);fill.style.width=(p*100).toFixed(1)+'%';pct.textContent=Math.round(p*100);
if(t<1){requestAnimationFrame(step);return;}root.setAttribute('data-s','2');note.textContent='Verstuurd. We bellen u vandaag voor 17:00 terug.';
setTimeout(function(){root.setAttribute('data-s','0');fill.style.width='0';pct.textContent='0';btn.disabled=false;busy=false;},2800);});}
f.addEventListener('submit',function(e){e.preventDefault();touched=true;run();});
root.querySelector('.spb__in').addEventListener('focus',function(){touched=true;});
root.setAttribute('data-s','0');
if(!rm)(function loop(){setTimeout(function(){if(touched)return;run();loop();},busy?6200:700);})();
}
init(document.querySelector('.jouw-container'));
Meer uit knoppen
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 →