Pakketstatus die verspringt Nieuw
Volgstatus van een bestelling: een busje rijdt met draaiende wielen naar de volgende stop, de statuskop rolt naar de nieuwe stand en bij Bezorgd staat het pakje voor de deur van het huisje. De vier standen staan als echte geordende lijst onder de weg, de huidige vet. Inzetten op de bestelpagina van een webshop, in een track-en-trace-mail die naar de site linkt of in een klantaccount. In productie vul je de stand uit de API van je vervoerder.
Bestelling 20481, vandaag 14:00 tot 16:00
Ingepakt
Je koffie is gebrand en ingepakt in Utrecht.
- Besteld
- Ingepakt
- Onderweg
- Bezorgd
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.
<!-- Pakketstatus die verspringt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="k7p">
<div class="k7p__card">
<p class="k7p__order">Bestelling 20481, vandaag 14:00 tot 16:00</p>
<p class="k7p__status" aria-live="polite"><span class="k7p__s">Ingepakt</span></p>
<p class="k7p__note">Je koffie is gebrand en ingepakt in Utrecht.</p>
<div class="k7p__road" aria-hidden="true" style="--p:1">
<span class="k7p__track"><span class="k7p__done"></span></span>
<span class="k7p__stop" style="--i:0"></span><span class="k7p__stop" style="--i:1"></span><span class="k7p__stop" style="--i:2"></span><span class="k7p__stop" style="--i:3"></span>
<svg class="k7p__house" viewBox="0 0 22 22"><path d="M2 10 11 2.5 20 10v10H2z" fill="#fff" stroke="#0a0a0a" stroke-width="1.6" stroke-linejoin="round"/><path d="M9 20v-6h4v6" fill="none" stroke="#0a0a0a" stroke-width="1.6"/></svg>
<span class="k7p__box"></span>
<span class="k7p__van"><svg viewBox="0 0 36 22"><path d="M1 3a2 2 0 0 1 2-2h19v15H1z" fill="#F5480F"/><path d="M22 6h7l5 5v5H22z" fill="#0a0a0a"/><path d="M25 8h3.5l3 3H25z" fill="#fff"/><g class="k7p__wh"><circle cx="8" cy="17" r="3.6" fill="#0a0a0a"/><path d="M8 14.6v4.8" stroke="#fff" stroke-width="1.2"/></g><g class="k7p__wh"><circle cx="27" cy="17" r="3.6" fill="#0a0a0a"/><path d="M27 14.6v4.8" stroke="#fff" stroke-width="1.2"/></g></svg></span>
</div>
<ol class="k7p__labels"><li>Besteld</li><li>Ingepakt</li><li>Onderweg</li><li>Bezorgd</li></ol>
<button class="k7p__next" type="button">Volgende status</button>
</div>
</div>
</div>/* Pakketstatus die verspringt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.k7p{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;box-sizing:border-box;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;text-align:left;padding:10px 12px}
.k7p *{box-sizing:border-box}
.k7p__card{width:100%;max-width:350px;background:#fff;border:1px solid rgba(10,10,10,.14);border-radius:8px;padding:11px 14px 12px}
.k7p__order{margin:0;font-size:12px;color:#4d4d4d}
.k7p__status{height:24px;margin:2px 0 0;overflow:hidden;font-size:18px;font-weight:700;line-height:24px}
.k7p__s{display:block}
.k7p__s.is-in{animation:k7p-in .4s cubic-bezier(.3,1.3,.5,1)}
@keyframes k7p-in{from{transform:translateY(100%);opacity:0}to{transform:none;opacity:1}}
.k7p__note{margin:0;min-height:17px;font-size:12px;line-height:1.4;color:#4d4d4d}
.k7p__road{position:relative;height:36px;margin:6px 0 2px}
.k7p__track{position:absolute;left:18px;right:40px;bottom:6px;height:3px;background:#e6e3de}
.k7p__done{position:absolute;left:0;top:0;bottom:0;width:calc(var(--p) / 3 * 100%);background:#0a0a0a;transition:width .9s cubic-bezier(.45,0,.3,1)}
.k7p__stop{position:absolute;bottom:2px;left:calc(18px + var(--i) / 3 * (100% - 58px) - 5px);width:11px;height:11px;border:2px solid #c9c4bc;border-radius:50%;background:#fff}
.k7p__road[style*="--p:1"] .k7p__stop[style*="--i:0"],.k7p__road[style*="--p:1"] .k7p__stop[style*="--i:1"],.k7p__road[style*="--p:2"] .k7p__stop:not([style*="--i:3"]),.k7p__road[style*="--p:3"] .k7p__stop,.k7p__road[style*="--p:0"] .k7p__stop[style*="--i:0"]{border-color:#0a0a0a;background:#0a0a0a}
.k7p__house{position:absolute;right:0;bottom:0;width:22px;height:22px}
.k7p__box{position:absolute;right:26px;bottom:2px;width:10px;height:9px;background:#c9935a;border:1.5px solid #0a0a0a;border-radius:1px;opacity:0;transform:translateY(-14px)}
.k7p__road[style*="--p:3"] .k7p__box{animation:k7p-box .5s 1.1s cubic-bezier(.3,1.5,.5,1) forwards}
@keyframes k7p-box{to{opacity:1;transform:none}}
.k7p__van{position:absolute;bottom:9px;left:calc(var(--p) / 3 * (100% - 58px));width:36px;height:22px;transition:left .9s cubic-bezier(.45,0,.3,1)}
.k7p__van svg{display:block;width:36px;height:22px;overflow:visible}
.k7p__road[style*="--p:3"] .k7p__van{opacity:0;transition:left .9s cubic-bezier(.45,0,.3,1),opacity .35s 1s}
.k7p__wh{transform-box:fill-box;transform-origin:center}
.k7p__road.is-drive .k7p__wh{animation:k7p-wh .3s linear 3}
.k7p__road.is-drive .k7p__van svg{animation:k7p-bob .3s ease-in-out 3}
@keyframes k7p-wh{to{transform:rotate(360deg)}}
@keyframes k7p-bob{50%{transform:translateY(-1.5px)}}
.k7p__labels{display:flex;justify-content:space-between;list-style:none;margin:0 0 10px;padding:0;font-size:12px;color:#5b5b5b}
.k7p__labels li.is-cur{color:#0a0a0a;font-weight:700}
.k7p__next{height:32px;padding:0 12px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 13px/1 'Switzer',system-ui,sans-serif;cursor:pointer;transition:background-color .15s}
.k7p__next:hover{background:#333}
.k7p__next:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.k7p__done,.k7p__van,.k7p__road[style*="--p:3"] .k7p__van{transition:none}.k7p__road.is-drive .k7p__wh,.k7p__road.is-drive .k7p__van svg,.k7p__s.is-in{animation:none}.k7p__road[style*="--p:3"] .k7p__box{animation:none;opacity:1;transform:none}}// Pakketstatus die verspringt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie
// root = het element waarin de HTML staat
function init(root){
var w = root.querySelector('.k7p'); if (!w) return;
var road = w.querySelector('.k7p__road'), s = w.querySelector('.k7p__status'), note = w.querySelector('.k7p__note'), lis = w.querySelectorAll('.k7p__labels li'), btn = w.querySelector('.k7p__next');
var ST = [['Besteld', 'We hebben je bestelling om 09:12 ontvangen.'], ['Ingepakt', 'Je koffie is gebrand en ingepakt in Utrecht.'], ['Onderweg', 'De bezorger rijdt, je bent stop 6 van 14.'], ['Bezorgd', 'Om 14:37 afgegeven bij de voordeur.']];
var p = 1, tm = 0;
function draw(anim) {
road.setAttribute('style', '--p:' + p);
s.innerHTML = '<span class="k7p__s' + (anim ? ' is-in' : '') + '">' + ST[p][0] + '</span>';
note.textContent = ST[p][1];
lis.forEach(function (li, i) { li.classList.toggle('is-cur', i === p); if (i === p) li.setAttribute('aria-current', 'step'); else li.removeAttribute('aria-current'); });
btn.textContent = p < 3 ? 'Volgende status' : 'Opnieuw volgen';
if (anim && p > 0) { road.classList.remove('is-drive'); void road.offsetWidth; road.classList.add('is-drive'); clearTimeout(tm); tm = setTimeout(function () { road.classList.remove('is-drive'); }, 950); }
}
btn.addEventListener('click', function () { p = p < 3 ? p + 1 : 0; draw(true); });
draw(false);
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
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 →