Knop met bevestiging erboven Nieuw
Voor acties die je niet per ongeluk wilt doen, zonder volledige dialoog: een klik op Annuleren laat direct boven de knop een klein ballonnetje zien met "Weet je het zeker?" en de keuzes Nee (krijgt de focus, is de veilige keuze) en Ja. Escape, ergens anders klikken of wegtabben sluit het; na Ja volgt een regel met Ongedaan maken. Voor afspraken annuleren, een regel uit de winkelmand halen of een abonnement pauzeren; bij minder beweging verschijnt het ballonnetje zonder animatie.
Intake fysiotherapie
Do 16 okt, 14:30 in Vlaardingen
Weet je het zeker?
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.
<!-- Knop met bevestiging erboven · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="kib">
<div class="kib__card">
<div class="kib__info"><p class="kib__what">Intake fysiotherapie</p><p class="kib__when">Do 16 okt, 14:30 in Vlaardingen</p></div>
<div class="kib__act">
<button class="kib__btn" type="button" aria-expanded="false" aria-controls="kib-pop">Annuleren</button>
<div class="kib__pop" id="kib-pop" role="group" aria-label="Annuleren bevestigen" hidden>
<p class="kib__q">Weet je het zeker?</p>
<div class="kib__opts"><button class="kib__no" type="button">Nee</button><button class="kib__yes" type="button">Ja, annuleer</button></div>
</div>
<button class="kib__undo" type="button" hidden>Ongedaan maken</button>
</div>
</div>
<p class="kib__st" role="status"></p>
</div>
</div>/* Knop met bevestiging erboven · NedDev · eigen werk. */
.kib{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:6px;padding:12px 12px 10px;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.kib *,.kib *::before,.kib *::after{box-sizing:border-box}
.kib__card{width:min(340px,100%);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 12px 12px 16px;background:#fff;border:1px solid #e2dfda;border-radius:8px}
.kib__info{min-width:0}
.kib__what{margin:0;font:600 15px/1.3 'Switzer',sans-serif;transition:color .2s ease}
.kib__when{margin:2px 0 0;font:400 13px/1.3 'Switzer',sans-serif;color:#5d5953}
.kib__card.is-gone .kib__what{color:#8a857d;text-decoration:line-through;text-decoration-color:#F5480F;text-decoration-thickness:2px}
.kib__act{position:relative;flex:none}
.kib__btn,.kib__undo{appearance:none;min-height:40px;margin:0;padding:0 14px;border:1px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:600 14px/1 'Switzer',sans-serif;cursor:pointer;transition:background-color .16s ease}
.kib__btn:hover,.kib__undo:hover{background:#e8e5e0}
.kib__btn[aria-expanded="true"]{background:#0a0a0a;color:#fff}
.kib__pop{position:absolute;right:0;bottom:calc(100% + 12px);width:206px;padding:12px;background:#0a0a0a;color:#fff;border-radius:8px;transform-origin:85% 100%;animation:kib-in .18s cubic-bezier(.3,.7,.3,1)}
.kib__pop::after{content:'';position:absolute;right:26px;bottom:-6px;width:12px;height:12px;background:#0a0a0a;transform:rotate(45deg)}
@keyframes kib-in{from{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:none}}
.kib__q{margin:0 0 10px;font:600 14px/1.3 'Switzer',sans-serif}
.kib__opts{display:flex;gap:8px}
.kib__no,.kib__yes{appearance:none;flex:1;min-height:36px;margin:0;padding:0 10px;border-radius:4px;font:600 13px/1 'Switzer',sans-serif;cursor:pointer;transition:background-color .16s ease}
.kib__no{border:1px solid #fff;background:#fff;color:#0a0a0a}
.kib__no:hover{background:#e8e5e0}
.kib__yes{flex:1.4;border:1px solid #F5480F;background:#F5480F;color:#0a0a0a}
.kib__yes:hover{background:#ff5d24}
.kib__btn:focus-visible,.kib__undo:focus-visible{outline:2px solid #F5480F;outline-offset:3px}
.kib__no:focus-visible,.kib__yes:focus-visible{outline:2px solid #fff;outline-offset:2px}
.kib__st{min-height:18px;margin:0;font:400 13px/1.35 'Switzer',sans-serif;color:#5d5953;text-align:center}
@media (max-width:400px){.kib__pop{width:222px;padding:10px;bottom:calc(100% + 10px)}.kib__q{margin-bottom:8px}.kib__no,.kib__yes{min-height:32px}}
@media (prefers-reduced-motion:reduce){.kib__pop{animation:none}}// Knop met bevestiging erboven · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.kib');if(!w)return;
var card=w.querySelector('.kib__card'),btn=w.querySelector('.kib__btn'),pop=w.querySelector('.kib__pop'),no=w.querySelector('.kib__no'),yes=w.querySelector('.kib__yes'),undo=w.querySelector('.kib__undo'),st=w.querySelector('.kib__st');
function open(){pop.hidden=false;btn.setAttribute('aria-expanded','true');no.focus();}
function close(f){if(pop.hidden)return;pop.hidden=true;btn.setAttribute('aria-expanded','false');if(f)btn.focus();}
btn.addEventListener('click',function(){pop.hidden?open():close(true);});
no.addEventListener('click',function(){close(true);});
yes.addEventListener('click',function(){close(false);card.classList.add('is-gone');btn.hidden=true;undo.hidden=false;undo.focus();st.textContent='Afspraak van donderdag 16 oktober geannuleerd.';});
undo.addEventListener('click',function(){card.classList.remove('is-gone');undo.hidden=true;btn.hidden=false;btn.focus();st.textContent='Afspraak staat weer gepland.';});
pop.addEventListener('keydown',function(e){if(e.key==='Escape'){e.preventDefault();close(true);}});
w.addEventListener('focusout',function(e){if(!pop.hidden&&!pop.contains(e.relatedTarget)&&e.relatedTarget!==btn)close(false);});
document.addEventListener('pointerdown',function(e){if(!pop.hidden&&!pop.contains(e.target)&&e.target!==btn)close(false);});
}
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 →