Afbeelding laadt met blur-up Nieuw
Terwijl een foto laadt zie je een wazige mini-versie (LQIP van 20 px, ca. 250 bytes als data-URI in de HTML); zodra het echte beeld binnen is vloeit het van wazig naar scherp. loading="lazy" + decoding="async" + een onload-klasse, werkt overal; mislukt het laden dan volgt een nette foutstaat met "Opnieuw". De demo vertraagt het laden kunstmatig zodat je de overgang ziet.

Foto niet geladen

Foto niet geladen

Foto niet geladen
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.
<!-- Afbeelding laadt met blur-up · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="lbu">
<div class="lbu__grid">
<figure class="lbu__f" style="--lq:url(data:image/webp;base64,UklGRpwAAABXRUJQVlA4IJAAAAAQBACdASoUAAsAPpE4l0eloyIhMAgAsBIJZgCdACKykofffM4kLoKgTAD+6uX6y856gDSIOZ/NUYa0y+ZXklCHo1e/g4m/mRefSrbAgqOLg797I6J6pD6Ws2GpQ3s28+AW8loz5kj879cf3ISW7blIK4tZPMaA7pEebZiUMfzcbXuvR+K/DhtZNaLQWPwSAAA=)"><img alt="Duinpad naar het strand bij Zandvoort" width="900" height="491" decoding="async" loading="lazy" data-src="https://neddev.com/lab-media/lazy-blur-up-1.webp"><div class="lbu__err" role="alert" hidden><span>Foto niet geladen</span><button type="button" class="lbu__retry">Opnieuw</button></div><figcaption>Zandvoort</figcaption></figure>
<figure class="lbu__f" style="--lq:url(data:image/webp;base64,UklGRqwAAABXRUJQVlA4IKAAAABQBACdASoUAAsAPpE6l0eloyIhMAgAsBIJYwCdAYu47QcfjFaWX53Czac4AP7Ce50Au9PjO0hoSpALtQlT37DTfApovSyqNgx7y14vdXdj+rVQ59ER9U4kEJXWUm66v6TBDLGClx/neBH7Y99tKMKFmkFsXL/GCBbWizBPkSJCU4GbOsgFuey61YyuyXEhfIIMAlJ7tSBppB837hGsAAAA)"><img alt="Koffie en appeltaart op een terras" width="900" height="491" decoding="async" loading="lazy" data-src="https://neddev.com/lab-media/lazy-blur-up-2.webp"><div class="lbu__err" role="alert" hidden><span>Foto niet geladen</span><button type="button" class="lbu__retry">Opnieuw</button></div><figcaption>Delft</figcaption></figure>
<figure class="lbu__f" style="--lq:url(data:image/webp;base64,UklGRqgAAABXRUJQVlA4IJwAAACQAwCdASoUAAsAPpE6mEeloyKhMAgAsBIJZQATgABhCxOL53bwAP3D+0RO8JAjTOEbmNJNfsR6usbaNte9vtIYQK9L87/6V+7T5oR9TRF+mBLWb3/Tp6vu3l4k4PfUTfJnibMYsyM62R7M3CIMWOXx4s0f3zos3DUpGTrQNHRVLTgIGv7qpBU9B65QT+nCVTUQlqBz9wXrxDQAAAA=)"><img alt="Fietsers op een brede straat in Rotterdam" width="900" height="491" decoding="async" loading="lazy" data-src="https://neddev.com/lab-media/lazy-blur-up-3.webp"><div class="lbu__err" role="alert" hidden><span>Foto niet geladen</span><button type="button" class="lbu__retry">Opnieuw</button></div><figcaption>Rotterdam</figcaption></figure>
</div>
<div class="lbu__ctl"><button class="lbu__b" type="button" data-a="reload">Opnieuw laden</button><button class="lbu__b" type="button" data-a="err">Toon foutstaat</button><span class="lbu__st" aria-live="polite"></span></div>
</div>
</div>/* Afbeelding laadt met blur-up · NedDev · eigen werk. */
.lbu{position:absolute;inset:0;display:flex;flex-direction:column;gap:12px;padding:14px;background:#f4f3f1;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a}
.lbu__grid{flex:1;min-height:0;display:grid;grid-template-columns:1.3fr 1fr 1fr;gap:8px}
.lbu__f{position:relative;margin:0;min-height:0;border-radius:4px;overflow:hidden;background:#cfc9bf}
.lbu__f::before{content:'';position:absolute;inset:-12px;background:var(--lq) center/cover no-repeat;filter:blur(10px);transform:scale(1.05)}
.lbu__f img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;filter:blur(14px);transform:scale(1.06);transition:opacity .5s ease,filter .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
.lbu__f.is-loaded img{opacity:1;filter:none;transform:none}
.lbu__f::after{content:'';position:absolute;left:8px;top:8px;width:12px;height:12px;border-radius:50%;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;animation:lbu-rot .8s linear infinite;transition:opacity .2s}
.lbu__f.is-loaded::after,.lbu__f.is-err::after{opacity:0;animation:none}
.lbu__f figcaption{position:absolute;left:8px;bottom:7px;z-index:2;font:500 10px 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.6)}
.lbu__err{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;background:#e6e2da;font-size:11.5px;text-align:center;padding:8px}
.lbu__err[hidden]{display:none}
.lbu__retry,.lbu__b{appearance:none;border:1px solid #0a0a0a;background:#fff;color:#0a0a0a;font:600 11.5px 'Switzer',sans-serif;padding:6px 10px;border-radius:999px;cursor:pointer;transition:background-color .16s,color .16s}
.lbu__retry:hover,.lbu__b:hover{background:#0a0a0a;color:#fff}
.lbu__retry:focus-visible,.lbu__b:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.lbu__ctl{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.lbu__st{font:500 10px 'JetBrains Mono',monospace;color:#5f5a54;text-transform:uppercase;letter-spacing:.06em}
@keyframes lbu-rot{to{transform:rotate(1turn)}}
@media (prefers-reduced-motion:reduce){.lbu__f img{transition:opacity .2s}.lbu__f::after{animation-duration:2.4s}}
@media (max-width:420px){.lbu{gap:8px;padding:10px}.lbu__st{display:none}}// Afbeelding laadt met blur-up · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.lbu')||root;
var figs=[].slice.call(root.querySelectorAll('.lbu__f')),st=root.querySelector('.lbu__st'),run=0;
function load(f,delay,fail){var img=f.querySelector('img'),err=f.querySelector('.lbu__err');f.classList.remove('is-loaded','is-err');err.hidden=true;img.removeAttribute('src');var my=run;
setTimeout(function(){if(my!==run)return;
if(fail){f.classList.add('is-err');err.hidden=false;return;}
img.onload=function(){if(my!==run)return;(img.decode?img.decode():Promise.resolve()).catch(function(){}).then(function(){f.classList.add('is-loaded');if(root.querySelectorAll('.is-loaded').length===figs.length)st.textContent='Alle foto\'s geladen';});};
img.onerror=function(){f.classList.add('is-err');err.hidden=false;};
img.src=img.getAttribute('data-src');},delay);}
function all(failIdx){run++;st.textContent='Laden met trage verbinding';figs.forEach(function(f,i){load(f,700+i*550,i===failIdx);});}
root.querySelector('[data-a="reload"]').addEventListener('click',function(){all(-1);});
root.querySelector('[data-a="err"]').addEventListener('click',function(){all(1);});
figs.forEach(function(f){f.querySelector('.lbu__retry').addEventListener('click',function(){var r=++run;load(f,600,false);run=r;});});
if('IntersectionObserver' in window){var io=new IntersectionObserver(function(es){if(es[0].isIntersecting){io.disconnect();all(-1);}});io.observe(root);}else all(-1);
}
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 →