Hoe afbeeldingen en media Layout Shift veroorzaken (en hoe je het oplost)

De complete gids voor het voorkomen van CLS door afbeeldingen, video's, iframes, responsieve afbeeldingen en media embeds

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-04-08

Hoe afbeeldingen en media Layout Shift veroorzaken (en hoe je het oplost)

De 2025 Web Almanac plakt een getal op wat ik steeds in de praktijk zie: 62% van de mobiele pagina's heeft minstens één afbeelding zonder expliciete breedte en hoogte. Dat maakt media zonder afmetingen de nummer één oorzaak van Cumulative Layout Shift op het web. En elk van deze verschuivingen is te voorkomen met technieken die al sinds 2019 bestaan.

Laatst beoordeeld door Arjen Karel in maart 2026

De browser weet niet hoe groot je afbeelding is

Elke layout shift die door een afbeelding wordt veroorzaakt, komt op één ding neer. De browser weet niet hoeveel ruimte hij moet reserveren voordat de afbeelding laadt.

Wanneer de browser een <img>-tag zonder afmetingen tegenkomt, stopt hij niet totdat hij de afmetingen van de afbeelding kent. Nee, hij reserveert gewoon een ruimte van 0x0 pixels. Vervolgens wordt de afbeelding gedownload, herberekt de browser de lay-out en springt alles onder de afbeelding naar beneden. Die sprong is je CLS.

Hoe breedte en hoogte layout shift voorkomen

De enige oplossing voor een layout shift is het reserveren van de juiste ruimte. De makkelijkste manier om dat te doen is door simpelweg de juiste (intrinsieke) breedte en hoogte van de afbeelding in te stellen. In 2019 en 2020 brachten alle grote browsers een functie uit die de werking van width en height attributen veranderde. Browsers gebruiken ze nu om een aspect ratio te berekenen voordat de afbeelding downloadt.

Wanneer je dit schrijft:

<img src="hero.jpg" width="800" height="450" alt="Description">

Genereert de browser intern dit:

img[Attributes Style] {
    aspect-ratio: auto 800 / 450;
}

Voor responsieve afbeeldingen, voeg je deze CSS toe:

img {
    height: auto;
    max-width: 100%;
}

Browsers hoeven niet het volledige afbeeldingsbestand te downloaden om de afmetingen te berekenen. De browser kent de verhouding en reserveert de verticale ruimte. De CSS doet het laatste deel: indamming (containment). height: auto berekent de hoogte uit de verhouding. max-width: 100% voorkomt dat de afbeelding zijn container overschrijdt.

Dingen die de oplossing ongedaan maken

Breedte en hoogte attributen zijn alles wat je nodig hebt om te voorkomen dat afbeeldingen layout shifts veroorzaken. Maar er zijn nog steeds een paar veelvoorkomende patronen die het werk ongedaan maken en ervoor zorgen dat afbeeldingen layout shifts veroorzaken, zelfs met afmetingen en CSS.

width:auto in CSS

Dit is degene die ik het meest zie en die de meeste tijd verspilt bij het debuggen. De developer stelt width en height in op elke afbeelding, doet alles goed in de HTML, maar ergens in het CSS-bestand staat een extra width:auto voor afbeeldingen.

img {
    width: auto;
    height: auto;
    max-width: 100%;
}

Het probleem is width: auto. Omdat de interne verhouding van de browser de laagste CSS-prioriteit heeft, overschrijft elke regel deze. width: auto verwijdert de breedte die de browser gebruikte om de hoogte te berekenen. Beide afmetingen worden onbekend. De afbeelding wordt gerenderd op 0x0 totdat het bestand is gedownload en de definitieve afmetingen bekend zijn.

Het instellen van aspect-ratio in CSS lost dit niet op. Met width: auto behandelt de browser de breedte in eerste instantie als 0. Een aspect ratio berekend vanuit 0 levert nog steeds 0x0 op.

Wat deze lastig te vangen maakt is browser caching. Als de afbeelding in de browser cache zit, zijn de werkelijke afmetingen direct beschikbaar en treedt er geen verschuiving op. Ik heb dit op tientallen klantwebsites gedebugd en het was altijd in de cache op de machine van de developer.

De oplossing:

img {
    height: auto;
    max-width: 100%;
}

Verwijder width: auto. Behoud height: auto en max-width: 100%. Dit is het patroon dat wordt aanbevolen door web.dev.

Snelle check: klik met de rechtermuisknop op een willekeurige afbeelding, inspecteer deze, kijk naar de computed styles. Als je width: auto ziet, is dat je probleem. Voor de volledige gids, zie layout shift veroorzaakt door auto-sizing afbeeldingen oplossen.

Verkeerde afbeeldingsafmetingen

Herinner je de intern gegenereerde aspect ratio? Dit is waar het wat technischer wordt. Het auto keyword vertelt de browser: gebruik deze verhouding als tijdelijke aanduiding (placeholder), maar zodra de daadwerkelijke afbeelding laadt, schakel dan over naar de echte afmetingen. Als je verkeerde waarden instelt (width="4" height="3" op een 16:9 afbeelding), reserveert de browser in eerste instantie 4:3 ruimte, en corrigeert dit vervolgens naar 16:9 wanneer de afbeelding laadt. Die correctie is een layout shift. Gebruik altijd de werkelijke pixelafmetingen van de afbeelding.

Wanneer CSS aspect-ratio de betere keuze is

Breedte/hoogte attributen zijn de standaard aanpak en altijd de beste aanpak, maar soms staat je CMS niet toe dat je afbeeldingsafmetingen toevoegt (en dat gebeurt vaker dan je denkt!). In dat geval kun je controleren hoeveel ruimte er wordt gereserveerd door de CSS aspect ratio te gebruiken. Als je hero-afbeelding bijvoorbeeld de .hero class heeft, kun je de ruimte zo reserveren:

img.hero {
    aspect-ratio: 16 / 9;
    width: 100%;
}

Werkt in alle moderne browsers (Chrome 88+, Firefox 87+, Safari 15+) en op elk element, niet alleen afbeeldingen en video's.

Video's, iframes en SVG's

Video's

Zelfde probleem, zelfde oplossing. Stel breedte en hoogte in om overeen te komen met de videoresolutie:

<video src="demo.mp4" width="1280" height="720" autoplay muted loop></video>

Voeg height: auto; max-width: 100%; toe in CSS. Eén ding om op te letten: stel de afmetingen in zodat deze overeenkomen met de videoresolutie, niet met de poster image. Als deze verschillen, krijg je een verschuiving wanneer het afspelen begint.

Iframes

In tegenstelling tot afbeeldingen berekenen iframes geen aspect ratio uit hun attributen. Zonder expliciete afmetingen staan ze standaard op 300x150 pixels. Voor de meeste embeds is dat fout. Voor iframes kun je de aspect-ratio het beste zo instellen:

.responsive-iframe {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
}

Beter nog, laad het iframe helemaal niet. Voor YouTube, Vimeo, Google Maps en social embeds ben ik jaren geleden al gestopt met het laden van iframes bij het laden van de pagina. Toon een statische placeholder image met de juiste aspect ratio. Wanneer het iframe zichtbaar wordt, wisselt JavaScript het in voor het echte iframe. De verschuiving van de wissel gebeurt binnen 500 ms na gebruikersinvoer (user input) en wordt opzettelijk uitgesloten van CLS.

Voor implementatiedetails, zie perfecte YouTube embeds en Google Maps zonder PageSpeed te verliezen.

SVG's

SVG's geladen via <img> hebben breedte en hoogte op de tag nodig, net als rasterafbeeldingen. Inline <svg>-elementen hebben een viewBox nodig met CSS aspect-ratio. Zonder beide staan ze standaard op 300x150.

Responsieve afbeeldingen

Houd dezelfde verhouding over alle srcset bronnen

Alle afbeeldingen in een srcset moeten dezelfde aspect ratio delen. Als dat zo is, is één set breedte/hoogte op de <img> voldoende:

<img
    src="hero-800.jpg"
    srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 800px"
    width="800" height="450"
    alt="Hero image">

800:450 is dezelfde verhouding over alle drie de varianten. Ongeacht welke de browser kiest, de gereserveerde ruimte is correct. Als je verschillende verhoudingen nodig hebt, gebruik dan in plaats daarvan <picture> met <source>-elementen.

Art direction: verschillende verhoudingen per breakpoint

Wanneer je verschillende crops serveert op verschillende viewport-breedtes, moet je het <picture>-element gebruiken. Stel width en height in op elke <source>:

<picture>
    <source
        media="(max-width: 799px)"
        srcset="hero-mobile.jpg"
        width="480" height="600">
    <source
        media="(min-width: 800px)"
        srcset="hero-desktop.jpg"
        width="1200" height="400">
    <img
        src="hero-desktop.jpg"
        width="1200" height="400"
        alt="Product hero image">
</picture>

Chrome en Safari pikken de juiste afmetingen op van welke <source> dan ook actief is. Firefox doet dit niet (bug 1694741). Het gebruikt altijd de fallback-afmetingen van <img>. Workaround: match de breakpoints met CSS media queries.

picture img {
    width: 100%;
    height: auto;
}
@media (max-width: 799px) {
    picture img {
        aspect-ratio: 480 / 600;
    }
}
@media (min-width: 800px) {
    picture img {
        aspect-ratio: 1200 / 400;
    }
}

Als al je crops dezelfde verhouding delen, maakt de Firefox-bug niet uit.

Vaste containers, carrousels en containment

object-fit voor containers met een vaste grootte

Product card grids waarbij elke kaart dezelfde hoogte heeft, maar afbeeldingen verschillende verhoudingen hebben. Vergrendel de container, laat de afbeelding deze vullen:

.product-image {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    object-position: center;
}
<img
    src="product.jpg"
    width="400" height="600"
    class="product-image"
    alt="Product name">

De grootte wordt vergrendeld voordat de afbeelding laadt. Dit vervangt ook CSS background images. Background images kunnen niet lazy worden geladen, de preload scanner vindt ze niet en je kunt geen fetchpriority gebruiken. Een <img> met object-fit: cover geeft je al die controle.

Carrousels

Slide-overgangen die left, width of margin animeren, triggeren een herberekening van de lay-out. Omdat autoplay geen gebruikersinvoer (user input) is, telt elke verschuiving mee voor CLS. Zet de container vast met een vaste aspect ratio. Animeer in plaats daarvan met transform: translateX(). Transforms draaien op de GPU en triggeren nooit lay-out.

Containment voor embeds die je niet kunt controleren

Ad slots, third-party widgets, door gebruikers gegenereerde content. Je hebt geen controle over wat ze renderen en je kunt ze niet clippen. Het realistische doel is om de verschuiving te minimaliseren, niet om deze te elimineren.

Begin met het reserveren van ruimte:

.ad-slot {
    min-height: 250px;
    contain: layout style;
}

De min-height zorgt voor de grote winst. Als de advertentie laadt op 250px of minder, is er geen verschuiving. Als deze laadt op 300px, krijg je een verschuiving van 50px in plaats van een verschuiving van 300px vanaf nul. Dat verschil is belangrijk.

contain: layout doet iets anders. Het voorkomt niet dat de container groeit. Het isoleert wat er binnenin gebeurt. Wanneer het advertentienetwerk scripts injecteert die hun eigen content reflowen (het formaat van iframes wijzigen, nieuwe elementen injecteren, de interne lay-out herberekenen), blijven die herberekeningen binnen de container. Zonder containment triggert elke interne reflow in de advertentie een herberekening van de lay-out voor de hele pagina. Met containment slaat de browser alles buiten de box over. Dat maakt de pagina responsiever terwijl advertenties worden geladen.

contain: style voorkomt dat CSS-counters en andere stijl-neveneffecten weglekken. Goedkope verzekering.

Voor de min-height waarde controleer je de meest voorkomende formaten van de creatives van je advertentieprovider en kies je degene die de meerderheid van de vertoningen (impressions) dekt. Als 90% van je advertenties 250px is en 10% 300px, stel dit dan in op 250px en accepteer de incidentele kleine verschuiving. Het instellen op 300px betekent dat 90% van de paginaweergaves 50px lege ruimte heeft die instort wanneer een kleinere advertentie wordt geladen. Die instorting is ook een layout shift.

Er is geen perfect antwoord voor advertenties. Het doel is de kleinst mogelijke verschuiving over de meeste paginaweergaves.

Hoe je afbeeldings-CLS vindt

Je zult afbeeldings-CLS niet opvangen onder normale browseromstandigheden. Je browser cache heeft de afmetingen al van een vorig bezoek, dus de verschuiving gebeurt nooit. Om te zien wat je echte gebruikers zien, open je DevTools (F12), ga je naar het Network-tabblad en vink je "Disable cache" aan. De cache is alleen uitgeschakeld zolang DevTools open is. Als alternatief kun je een incognitovenster gebruiken.

Real User Monitoring

Begin met CoreDash of een andere RUM-tool. CLS-attributiedata laat precies zien welke elementen verschoven zijn. Navigeer naar CLS, kijk naar de attributie Element tabel. Filter op afbeelding en je krijgt elk afbeeldingselement dat is beïnvloed door layout shifts, geordend op impact.

Chrome DevTools

Schakel de cache uit in het Network-tabblad, throttle naar Slow 4G, schakel screenshots in, en herlaad. Let op visuele sprongen. Open vervolgens het Performance-paneel en zoek naar "Layout Shift"-vermeldingen. Klik op een verschuiving om de node, de score en of deze recente gebruikersinvoer (user input) had te zien.

Core Web Vitals Visualizer

De Core Web Vitals Visualizer extensie markeert elke layout shift met een gekleurde overlay. Ik gebruik dit als mijn eerste stap voordat ik het Performance-paneel open. Herlaad met de extensie actief en je ziet precies wat er bewoog.

Snelle checklist voor CLS-oplossingen

Element CLS-oorzaak Oplossing
<img> Ontbrekende breedte/hoogte Voeg width en height toe; gebruik height: auto; max-width: 100%; in CSS
<img> CSS width: auto die afmetingen overschrijft Verwijder width: auto; behoud alleen height: auto
<img> Verkeerde breedte/hoogte waarden Gebruik de werkelijke pixelafmetingen van de afbeelding
<video> Ontbrekende breedte/hoogte Voeg width en height toe die overeenkomen met de videoresolutie
<iframe> Standaard 300x150 CSS aspect-ratio: 16 / 9; width: 100%; of het facade-patroon
<picture> Verschillende verhoudingen per source (Firefox-bug) Stel breedte/hoogte in op elke <source>; voeg CSS media query fallback toe
<img srcset> Gemengde verhoudingen in srcset Zelfde verhouding voor alle bronnen; stel breedte/hoogte in op de <img>
JS lazy loading 1x1 placeholder met verkeerde verhouding Gebruik native loading="lazy" of match de verhouding van de placeholder
Carrousel Autoplay + lay-out-triggerende overgangen Vaste aspect-ratio container; transform voor overgangen
SVG Geen ingebouwde afmetingen Breedte/hoogte op <img> of viewBox + CSS aspect-ratio
Ad slots / embeds Onbekende afmetingen min-height + contain: layout style

Hoe het web ervoor staat met afbeeldings-CLS

De 2025 Web Almanac cijfers:

  • 62% van de mobiele pagina's heeft minstens één afbeelding zonder afmetingen. Een daling ten opzichte van 66% in 2024. Nog steeds de meerderheid.
  • 65% van de desktop pagina's heeft afbeeldingen zonder afmetingen. Een daling ten opzichte van 69%.
  • Op het p75-niveau heeft een desktop pagina 9 afbeeldingen zonder afmetingen. Mobiel heeft er 8.
  • Mediane hoogte van afbeeldingen zonder afmetingen: 111px op desktop, 98px op mobiel. Genoeg om een paragraaf te verschuiven.
  • 72% van de desktop- en 81% van de mobiele origins slaagt voor CLS. Een stijging ten opzichte van 62% in 2021.

CLS is de afgelopen vier jaar meer verbeterd dan enige andere Core Web Vital. Afbeeldingen zonder afmetingen zijn nog steeds de grootste bijdrager. Los dit ene probleem op en layout shifts verdwijnen op de meeste sites.

Gerelateerde gidsen

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.


I make sites pass Core Web Vitals.

500K+ pages for major European publishers and e-commerce platforms. I write the fixes and verify them with field data.

How I work

Vragen over afbeeldings- en media-CLS beantwoord

Waarom veroorzaakt width:auto op afbeeldingen layout shift, zelfs wanneer de breedte- en hoogte-attributen zijn ingesteld?

De interne aspect ratio van de browser op basis van de width/height attributen heeft de laagste CSS-prioriteit. width: auto overschrijft deze, waardoor beide afmetingen onbekend worden. De afbeelding wordt gerenderd op 0x0 totdat het bestand is gedownload. Verwijder width: auto en behoud alleen height: auto; max-width: 100%;.

Heb ik ook breedte en hoogte nodig op video- en iframe-elementen?

Ja voor video. Hetzelfde mechanisme. Iframes zijn anders: ze berekenen geen verhouding uit attributen en staan standaard op 300x150. Gebruik CSS aspect-ratio of het facade-patroon.

Hoe voorkom ik CLS met het picture-element wanneer aspect ratio's verschillen per breakpoint?

Stel breedte en hoogte in op elke <source>. Chrome en Safari gebruiken de juiste afmetingen. Firefox heeft een bug waarbij het altijd de <img> fallback gebruikt. Voeg CSS media queries toe met de juiste aspect-ratio per breakpoint als een workaround.

Veroorzaakt lazy loading layout shift?

Niet als de afbeelding breedte- en hoogte-attributen heeft. Maar het lazy loaden van above-the-fold afbeeldingen vertraagt LCP zonder enig voordeel. Gebruik nooit loading="lazy" op afbeeldingen in de initiële viewport.

Waarom toont Lighthouse een goede CLS maar laat mijn field data layout shifts zien?

Lighthouse draait op een warme browser met een snel netwerk. Het vangt het width: auto-probleem niet op omdat het HTML-attributen controleert, niet de berekende CSS-stijlen (computed styles). Verifieer CLS altijd met field data van CrUX of een RUM-tool zoals CoreDash.

Hoe afbeeldingen en media Layout Shift veroorzaken (en hoe je het oplost)Core Web Vitals Hoe afbeeldingen en media Layout Shift veroorzaken (en hoe je het oplost)