Voortgang die eindigt met een vlag New
A progress bar for the first steps in an account. Each completed step moves the bar along; at the last one the folded flag at the end is hoisted, waves briefly and gives off a few short strokes. Then it is done, without a confetti storm. Use it for onboarding in a web shop, customer portal or SaaS, or for a profile that needs completing. Real progressbar with aria-valuenow.
Je webshop klaarzetten
Stap 1 van 4: logo toevoegen
How to use it
- Paste the HTML where the components 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.
<!-- Voortgang die eindigt met een vlag · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="k7f">
<div class="k7f__card">
<p class="k7f__h">Je webshop klaarzetten</p>
<p class="k7f__step" aria-live="polite">Stap 1 van 4: logo toevoegen</p>
<div class="k7f__track" role="progressbar" aria-label="Webshop klaarzetten" aria-valuemin="0" aria-valuemax="4" aria-valuenow="0" aria-valuetext="0 van 4 stappen klaar">
<span class="k7f__line"><span class="k7f__fill"></span><span class="k7f__dot" style="--f:.25"></span><span class="k7f__dot" style="--f:.5"></span><span class="k7f__dot" style="--f:.75"></span></span>
<span class="k7f__pole" aria-hidden="true"><span class="k7f__flag"></span><span class="k7f__ray" style="--a:-60deg"></span><span class="k7f__ray" style="--a:-20deg"></span><span class="k7f__ray" style="--a:20deg"></span><span class="k7f__ray" style="--a:60deg"></span><span class="k7f__ray" style="--a:100deg"></span></span>
</div>
<button class="k7f__btn" type="button">Stap afronden</button>
</div>
</div>
</div>/* Voortgang die eindigt met een vlag · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.k7f{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:12px}
.k7f *{box-sizing:border-box}
.k7f__card{width:100%;max-width:340px;background:#fff;border:1px solid rgba(10,10,10,.14);border-radius:8px;padding:14px}
.k7f__h{margin:0 0 3px;font-size:15px;font-weight:700}
.k7f__step{margin:0;min-height:18px;font-size:13px;color:#4d4d4d}
.k7f__track{position:relative;height:56px;margin:8px 0 12px}
.k7f__line{position:absolute;left:0;right:40px;bottom:8px;height:4px;background:#e6e3de;border-radius:2px}
.k7f__fill{position:absolute;left:0;top:0;bottom:0;width:0;background:#F5480F;border-radius:2px;transition:width .5s cubic-bezier(.4,1.2,.5,1)}
.k7f__dot{position:absolute;top:50%;left:calc(var(--f) * 100%);width:12px;height:12px;margin:-6px 0 0 -6px;border:2px solid #c9c4bc;border-radius:50%;background:#fff;transition:background-color .25s,border-color .25s,transform .25s}
.k7f__dot.is-on{border-color:#0a0a0a;background:#0a0a0a;transform:scale(1.15)}
.k7f__pole{position:absolute;right:38px;bottom:4px;width:3px;height:52px;background:#0a0a0a;border-radius:2px}
.k7f__flag{position:absolute;left:3px;top:2px;width:30px;height:18px;background:#c9c4bc;clip-path:polygon(0 0,100% 0,80% 50%,100% 100%,0 100%);transform-origin:0 50%;transform:translateY(28px) scaleX(.35);transition:transform .9s cubic-bezier(.3,1.3,.5,1),background-color .4s}
.k7f.is-done .k7f__flag{background:#F5480F;transform:none;animation:k7f-wave .9s .85s ease-in-out 2}
@keyframes k7f-wave{25%{transform:skewY(5deg) scaleX(.94)}75%{transform:skewY(-4deg)}}
.k7f__ray{position:absolute;left:18px;top:11px;width:2px;height:7px;background:#0a0a0a;border-radius:1px;opacity:0;transform:rotate(var(--a)) translateY(-14px)}
.k7f.is-done .k7f__ray{animation:k7f-ray .6s .9s ease-out}
@keyframes k7f-ray{0%{opacity:0;transform:rotate(var(--a)) translateY(-10px) scaleY(.3)}40%{opacity:1}100%{opacity:0;transform:rotate(var(--a)) translateY(-22px) scaleY(1)}}
.k7f__btn{height:34px;padding:0 14px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 13px/1 'Switzer',system-ui,sans-serif;cursor:pointer;transition:background-color .15s}
.k7f__btn:hover{background:#333}
.k7f__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.k7f__fill,.k7f__dot,.k7f__flag{transition:none}.k7f.is-done .k7f__flag,.k7f.is-done .k7f__ray{animation:none}}// Voortgang die eindigt met een vlag · © 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('.k7f'); if (!w) return;
var tr = w.querySelector('.k7f__track'), fill = w.querySelector('.k7f__fill'), dots = w.querySelectorAll('.k7f__dot'), stp = w.querySelector('.k7f__step'), btn = w.querySelector('.k7f__btn');
var S = ['logo toevoegen', 'eerste product plaatsen', 'iDEAL koppelen', 'live zetten'], n = 0;
function draw() {
fill.style.width = (n / 4 * 100) + '%';
dots.forEach(function (d, i) { d.classList.toggle('is-on', i < n); });
tr.setAttribute('aria-valuenow', n); tr.setAttribute('aria-valuetext', n + ' van 4 stappen klaar');
w.classList.toggle('is-done', n === 4);
stp.textContent = n < 4 ? 'Stap ' + (n + 1) + ' van 4: ' + S[n] : 'Klaar. Je winkel staat live op bakkerijjansen.nl.';
btn.textContent = n < 4 ? 'Stap afronden' : 'Opnieuw bekijken';
}
btn.addEventListener('click', function () { n = n < 4 ? n + 1 : 0; draw(); });
draw();
}
init(document.querySelector('.jouw-container'));
More components
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 →