Laadstanden in de knop Nieuw
Drie manieren om te laten zien dat een knop bezig is, in de knop zelf: een draaiende ring, drie verende puntjes en een balk die vol loopt. Het label blijft onzichtbaar staan zodat de knop niet van breedte verspringt; aria-busy en een statusregel vertellen schermlezers wat er gebeurt, dubbel klikken doet niets. Kies de ring voor betalen, de puntjes voor versturen en de balk als je de voortgang echt weet (uploaden). Bij minder beweging pulseren ze rustig in plaats van te draaien.
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.
<!-- Laadstanden in de knop · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="kls">
<div class="kls__col">
<button class="kls__b" type="button" data-k="spin" data-msg="Betaling wordt verwerkt" data-ok="Betaald"><span class="kls__l">Betaal € 84,50</span><span class="kls__ld" aria-hidden="true"><span class="kls__spin"></span></span></button>
<button class="kls__b" type="button" data-k="dots" data-msg="Aanvraag wordt verstuurd" data-ok="Verstuurd"><span class="kls__l">Offerte aanvragen</span><span class="kls__ld" aria-hidden="true"><span class="kls__dots"><span></span><span></span><span></span></span></span></button>
<button class="kls__b" type="button" data-k="bar" data-msg="Foto's worden geüpload" data-ok="Geüpload"><span class="kls__l">Upload 6 foto's</span><span class="kls__ld" aria-hidden="true"><span class="kls__bar"><span class="kls__fill"></span></span></span></button>
</div>
<p class="kls__st" role="status"></p>
</div>
</div>/* Laadstanden in de knop · NedDev · eigen werk. */
.kls{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:10px;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.kls *,.kls *::before,.kls *::after{box-sizing:border-box}
.kls__col{display:flex;flex-direction:column;gap:9px;width:min(230px,100%)}
.kls__b{appearance:none;position:relative;display:grid;place-items:center;min-height:44px;margin:0;padding:0 18px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 15px/1 'Switzer',sans-serif;cursor:pointer;transition:background-color .16s ease,color .16s ease}
.kls__b:nth-child(2){background:#F5480F;color:#0a0a0a}
.kls__b:nth-child(3){background:#fff;color:#0a0a0a;box-shadow:inset 0 0 0 1px #0a0a0a}
.kls__b:hover{background:#2b2926}
.kls__b:nth-child(2):hover{background:#ff5d24}
.kls__b:nth-child(3):hover{background:#faf9f7}
.kls__b:focus-visible{outline:2px solid #F5480F;outline-offset:3px}
.kls__b:nth-child(2):focus-visible{outline-color:#0a0a0a}
.kls__l,.kls__ld{grid-area:1/1}
.kls__ld{display:none;width:100%;align-items:center;justify-content:center}
.kls__b.is-busy{cursor:progress}
.kls__b.is-busy .kls__l{visibility:hidden}
.kls__b.is-busy .kls__ld{display:flex}
.kls__spin{width:20px;height:20px;border-radius:50%;border:2.5px solid rgba(255,255,255,.28);border-top-color:#fff;animation:kls-rot .7s linear infinite}
@keyframes kls-rot{to{transform:rotate(360deg)}}
.kls__dots{display:flex;gap:6px}
.kls__dots span{width:7px;height:7px;border-radius:50%;background:#0a0a0a;animation:kls-hop 1s cubic-bezier(.4,0,.2,1) infinite}
.kls__dots span:nth-child(2){animation-delay:.15s}
.kls__dots span:nth-child(3){animation-delay:.3s}
@keyframes kls-hop{0%,60%,100%{transform:translateY(0);opacity:.55}30%{transform:translateY(-6px);opacity:1}}
.kls__bar{display:block;width:62%;height:5px;background:#e8e5e0;border-radius:4px;overflow:hidden}
.kls__fill{display:block;width:0;height:100%;background:#F5480F}
.kls__b.is-ok .kls__l{color:inherit}
.kls__st{min-height:18px;margin:0;font:400 13px/1.35 'Switzer',sans-serif;color:#5d5953;text-align:center}
@media (prefers-reduced-motion:reduce){.kls__spin{animation:kls-puls 1.4s ease-in-out infinite;border-top-color:rgba(255,255,255,.28);background:rgba(255,255,255,.18)}.kls__dots span{animation:kls-puls 1.4s ease-in-out infinite}@keyframes kls-puls{0%,100%{opacity:.4}50%{opacity:1}}}// Laadstanden in de knop · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.kls');if(!w)return;
var st=w.querySelector('.kls__st');
[].forEach.call(w.querySelectorAll('.kls__b'),function(b){var l=b.querySelector('.kls__l'),orig=l.textContent;
b.addEventListener('click',function(){if(b.classList.contains('is-busy'))return;
b.classList.add('is-busy');b.setAttribute('aria-busy','true');b.setAttribute('aria-disabled','true');st.textContent=b.getAttribute('data-msg')+'...';
var dur=2400,fill=b.querySelector('.kls__fill');
function finish(){b.classList.remove('is-busy');b.removeAttribute('aria-busy');b.removeAttribute('aria-disabled');l.textContent=b.getAttribute('data-ok');st.textContent=b.getAttribute('data-ok')+'.';
setTimeout(function(){l.textContent=orig;if(fill)fill.style.width='0';},1800);}
if(fill){var t0=performance.now();(function step(t){var p=Math.min(1,(t-t0)/dur);fill.style.width=(p*100)+'%';if(p<1)requestAnimationFrame(step);else setTimeout(finish,150);})(t0);}
else setTimeout(finish,dur);});});
}
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 →