Preloader met teller, logo naar header New
Short preloader (about 1 s) counting 000 to 100, after which the large wordmark slides into place in the header and the hero is revealed. Plays once per session (sessionStorage in try/catch), then the page shows directly; a "Replay" button shows it again. The logo move is a FLIP animation with the Web Animations API. No counter or motion with prefers-reduced-motion.
[ Interieurbouw · Zaandam ]
Kasten, keukens en balies, op maat gemaakt in eigen werkplaats.
How to use it
- Paste the HTML where the hero styles 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.
<!-- Preloader met teller, logo naar header · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="plt"><div class="plt__site" aria-busy="true">
<div class="plt__hd" role="banner"><a class="plt__logo" href="#" aria-label="Kade Interieur, naar home">KADE</a><nav class="plt__nav" aria-label="Hoofdmenu"><a href="#">Projecten</a><a href="#">Werkplaats</a><a href="#">Contact</a></nav></div>
<div class="plt__hero"><p class="plt__k">[ Interieurbouw · Zaandam ]</p><h4 class="plt__h">Kasten, keukens en balies, op maat gemaakt in eigen werkplaats.</h4>
<button class="plt__again" type="button">Opnieuw afspelen</button></div></div>
<div class="plt__ld" aria-hidden="true"><div class="plt__bg"></div><span class="plt__big">KADE</span><span class="plt__n">000</span><span class="plt__bar"><i></i></span></div>
<p class="plt__sr" role="status"></p></div>
</div>/* Preloader met teller, logo naar header · NedDev · eigen werk. */
.plt{position:absolute;inset:0;background:#efe9e0;color:#1c1a17;font-family:'Switzer',system-ui,sans-serif;overflow:hidden;container-type:size}
.plt__site{position:absolute;inset:0;display:flex;flex-direction:column}
.plt__hd{display:flex;align-items:center;justify-content:space-between;padding:12px 14px}
.plt__logo{font:800 16px/1 'Switzer',sans-serif;letter-spacing:.14em;color:#1c1a17;text-decoration:none}
.plt.is-laden .plt__logo{visibility:hidden}
.plt__nav{display:flex;gap:12px}
.plt__nav a{font:500 12px 'Switzer',sans-serif;color:#1c1a17;text-decoration:none;transition:color .18s}
.plt__nav a:hover{color:#b8330a}
.plt a:focus-visible,.plt button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.plt__hero{flex:1;display:flex;flex-direction:column;justify-content:flex-end;padding:0 14px 16px;gap:8px}
.plt__k{margin:0;font:500 10px 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#6b645a}
.plt__h{margin:0;font:700 clamp(17px,6cqi,38px)/1.06 'Switzer',sans-serif;letter-spacing:-.025em;max-width:20ch}
.plt__again{align-self:flex-start;font:600 11px/1 'Switzer',sans-serif;padding:8px 12px;border-radius:999px;border:1px solid #1c1a17;background:transparent;color:#1c1a17;cursor:pointer;transition:background .18s,color .18s}
.plt__again:hover{background:#1c1a17;color:#efe9e0}
.plt__again:disabled{opacity:.4;cursor:wait}
.plt__ld{position:absolute;inset:0;display:none;z-index:5}
.plt.is-laden .plt__ld{display:block}
.plt__bg{position:absolute;inset:0;background:#1c1a17}
.plt__big{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font:800 clamp(34px,15cqi,96px)/1 'Switzer',sans-serif;letter-spacing:.14em;color:#efe9e0;transform-origin:0 0;white-space:nowrap}
.plt__n{position:absolute;right:14px;bottom:12px;font:500 clamp(22px,9cqi,56px)/1 'JetBrains Mono',monospace;color:#efe9e0;font-variant-numeric:tabular-nums}
.plt__bar{position:absolute;left:14px;bottom:14px;width:34%;height:2px;background:rgba(239,233,224,.2)}
.plt__bar i{display:block;height:100%;width:0;background:#F5480F}
.plt__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);margin:0}// Preloader met teller, logo naar header · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.plt')||root;
var site=root.querySelector('.plt__site'),ld=root.querySelector('.plt__ld'),bg=root.querySelector('.plt__bg'),big=root.querySelector('.plt__big'),num=root.querySelector('.plt__n'),bar=root.querySelector('.plt__bar i'),logo=root.querySelector('.plt__logo'),again=root.querySelector('.plt__again'),sr=root.querySelector('.plt__sr');
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches,KEY='neddev-lab-preloader-gezien';
function gezien(){try{return sessionStorage.getItem(KEY)==='1';}catch(e){return false;}}
function onthoud(){try{sessionStorage.setItem(KEY,'1');}catch(e){}}
function klaar(){root.classList.remove('is-laden');site.setAttribute('aria-busy','false');big.style.transform='';bg.style.opacity='';num.style.opacity='';again.disabled=false;sr.textContent='Pagina geladen';onthoud();}
function speel(){again.disabled=true;root.classList.add('is-laden');site.setAttribute('aria-busy','true');bg.style.opacity='1';num.style.opacity='1';big.style.transform='translate(-50%,-50%)';
if(rm){num.textContent='100';bar.style.width='100%';setTimeout(klaar,350);return;}
var t0=performance.now(),D=1000;
(function tel(now){var p=Math.min(1,(now-t0)/D),e=1-Math.pow(1-p,3),v=Math.round(e*100);num.textContent=('00'+v).slice(-3);bar.style.width=v+'%';
if(p<1)requestAnimationFrame(tel);else verhuis();})(t0);}
function verhuis(){var R=root.getBoundingClientRect();logo.style.visibility='hidden';root.classList.remove('is-laden');var hr=logo.getBoundingClientRect();root.classList.add('is-laden');
var br=big.getBoundingClientRect(),s=hr.width/br.width;
var from='translate('+(br.left-R.left)+'px,'+(br.top-R.top)+'px) scale(1)',to='translate('+(hr.left-R.left)+'px,'+(hr.top-R.top)+'px) scale('+s+')';
big.style.left='0';big.style.top='0';
var a=big.animate([{transform:from},{transform:to}],{duration:650,easing:'cubic-bezier(.7,0,.2,1)',fill:'forwards'});
bg.animate([{opacity:1},{opacity:0}],{duration:450,delay:200,easing:'ease-out',fill:'forwards'});num.animate([{opacity:1},{opacity:0}],{duration:200,fill:'forwards'});
a.onfinish=function(){logo.style.visibility='';big.style.left='';big.style.top='';a.cancel();bg.getAnimations().forEach(function(x){x.cancel();});num.getAnimations().forEach(function(x){x.cancel();});klaar();};}
again.addEventListener('click',speel);
if(gezien()){klaar();}else{speel();}
}
init(document.querySelector('.jouw-container'));
More hero styles
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 →