Comment les images et les médias causent le Layout Shift (et comment le corriger)

Le guide complet pour prévenir le CLS lié aux images, vidéos, iframes, images responsives et intégrations de médias

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

Comment les images et les médias causent le Layout Shift (et comment le corriger)

Le Web Almanac 2025 chiffre ce que je vois constamment sur le terrain : 62 % des pages mobiles ont au moins une image sans largeur ni hauteur explicites. Cela fait des médias sans dimension la cause principale du Cumulative Layout Shift sur le web. Et chacun de ces décalages est évitable grâce à des techniques qui existent depuis 2019.

Dernière révision par Arjen Karel en mars 2026

Le navigateur ne sait pas quelle est la taille de votre image

Chaque décalage de mise en page causé par une image se résume à une chose. Le navigateur ne sait pas combien d'espace réserver avant que l'image ne se charge.

Lorsque le navigateur rencontre une balise <img> sans dimensions, il ne s'arrête pas jusqu'à ce qu'il connaisse les dimensions de l'image. Non, il réserve simplement un espace de 0x0 pixels. Ensuite, l'image est téléchargée, le navigateur recalcule la mise en page et tout ce qui se trouve en dessous de l'image saute vers le bas. Ce saut est votre CLS.

Comment width et height préviennent le layout shift

La seule solution pour un décalage de mise en page est de réserver le bon espace. La façon la plus simple de le faire est de simplement définir la bonne largeur et hauteur (intrinsèques) de l'image. En 2019 et 2020, tous les principaux navigateurs ont intégré une fonctionnalité qui a modifié le fonctionnement des attributs width et height. Les navigateurs les utilisent désormais pour calculer un ratio d'aspect avant le téléchargement de l'image.

Quand vous écrivez ceci :

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

Le navigateur génère ceci en interne :

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

Pour les images responsives, ajoutez ce CSS :

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

Les navigateurs n'ont pas besoin de télécharger le fichier image complet pour calculer les dimensions. Le navigateur connaît le ratio et réserve l'espace vertical. Le CSS fait la dernière partie : le confinement. height: auto calcule la hauteur à partir du ratio. max-width: 100% empêche l'image de dépasser de son conteneur.

Les choses qui annulent la correction

Les attributs width et height sont tout ce dont vous avez besoin pour éviter que les images ne causent des décalages de mise en page. Mais il existe encore quelques modèles courants qui annulent le travail et font que les images causent des décalages de mise en page même avec des dimensions et du CSS.

width:auto en CSS

C'est celui que je vois le plus et celui qui fait perdre le plus de temps de débogage. Le développeur définit width et height sur chaque image, fait tout correctement dans le HTML, mais quelque part dans le fichier CSS, il y a un width:auto supplémentaire pour les images.

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

Le problème est width: auto. Parce que le ratio interne du navigateur a la priorité CSS la plus basse, toute règle l'écrase. width: auto supprime la largeur que le navigateur utilisait pour calculer la hauteur. Les deux dimensions deviennent inconnues. L'image est rendue à 0x0 jusqu'à ce que le fichier se télécharge et que les dimensions finales soient connues.

Définir aspect-ratio en CSS ne corrige pas cela. Avec width: auto, le navigateur traite initialement la largeur comme étant 0. Un ratio d'aspect calculé à partir de 0 produit toujours 0x0.

Ce qui rend ce problème difficile à repérer, c'est la mise en cache du navigateur. Si l'image est dans le cache du navigateur, les dimensions réelles sont disponibles immédiatement et aucun décalage ne se produit. J'ai débogué cela sur des dizaines de sites clients et c'était toujours mis en cache sur la machine du développeur.

La correction :

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

Supprimez width: auto. Conservez height: auto et max-width: 100%. C'est le modèle recommandé par web.dev.

Vérification rapide : faites un clic droit sur n'importe quelle image, inspectez-la, regardez les styles calculés. Si vous voyez width: auto, c'est votre problème. Pour la procédure complète, voir corriger le layout shift causé par les images auto-dimensionnées.

Mauvaises dimensions d'image

Vous vous souvenez du ratio d'aspect généré en interne ? C'est là que les choses deviennent un peu techniques. Le mot-clé auto dit au navigateur : utilisez ce ratio comme placeholder, mais une fois que l'image réelle se charge, passez aux dimensions réelles. Si vous définissez de mauvaises valeurs (width="4" height="3" sur une image 16:9), le navigateur réserve un espace 4:3 initialement, puis corrige en 16:9 lorsque l'image se charge. Cette correction est un layout shift. Utilisez toujours les dimensions réelles en pixels de l'image.

Quand CSS aspect-ratio est le meilleur choix

Les attributs width/height sont l'approche par défaut et toujours la meilleure approche, mais parfois votre CMS ne vous permet pas d'ajouter des dimensions d'image (et cela arrive plus souvent que vous ne le pensez !). Dans ce cas, vous pouvez contrôler la quantité d'espace réservée en utilisant le CSS aspect-ratio. Par exemple, si votre image hero a la classe .hero, vous pouvez réserver son espace comme ceci :

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

Fonctionne dans tous les navigateurs modernes (Chrome 88+, Firefox 87+, Safari 15+) et sur n'importe quel élément, pas seulement les images et les vidéos.

Vidéos, iframes, et SVGs

Vidéos

Même problème, même correction. Définissez width et height pour qu'ils correspondent à la résolution de la vidéo :

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

Ajoutez height: auto; max-width: 100%; en CSS. Une chose à surveiller : définissez les dimensions pour qu'elles correspondent à la résolution de la vidéo, pas à l'image poster. Si elles diffèrent, vous obtenez un décalage lorsque la lecture commence.

Iframes

Contrairement aux images, les iframes ne calculent pas de ratio d'aspect à partir de leurs attributs. Sans dimensions explicites, ils ont par défaut une taille de 300x150 pixels. Pour la plupart des intégrations, c'est faux. Pour les iframes, il est préférable de définir l'aspect-ratio comme ceci :

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

Mieux encore, ne chargez pas du tout l'iframe. Pour YouTube, Vimeo, Google Maps et les intégrations sociales, j'ai arrêté de charger les iframes au chargement de la page il y a des années. Affichez une image statique de placeholder avec le bon ratio d'aspect. Lorsque l'iframe devient visible, le JavaScript l'échange avec la véritable iframe. Le décalage lié à l'échange se produit dans les 500 ms suivant l'entrée utilisateur et est exclu du CLS par conception.

Pour les détails d'implémentation, voir intégrations YouTube parfaites et Google Maps sans perdre de PageSpeed.

SVGs

Les SVGs chargés via <img> ont besoin de width et height sur la balise, tout comme les images raster. Les éléments <svg> en ligne ont besoin d'une viewBox avec CSS aspect-ratio. Sans l'un ou l'autre, ils ont par défaut une taille de 300x150.

Images responsives

Gardez le même ratio pour toutes les sources srcset

Toutes les images dans un srcset doivent partager le même ratio d'aspect. Si c'est le cas, un ensemble de width/height sur la balise <img> suffit :

<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 est le même ratio pour les trois variantes. Peu importe celle que le navigateur choisit, l'espace réservé est correct. Si vous avez besoin de ratios différents, utilisez plutôt l'élément <picture> avec des éléments <source>.

Direction artistique : différents ratios par point de rupture

Lorsque vous servez des recadrages différents à différentes largeurs de viewport, vous devrez utiliser l'élément <picture>. Définissez width et height sur chaque <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 et Safari récupèrent les bonnes dimensions à partir de la <source> active. Firefox ne le fait pas (bug 1694741). Il utilise toujours les dimensions de fallback de l'<img>. Solution de contournement : faites correspondre les points de rupture avec des requêtes multimédias CSS.

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;
    }
}

Si tous vos recadrages partagent le même ratio, le bug de Firefox n'a pas d'importance.

Conteneurs fixes, carrousels, et confinement

object-fit pour les conteneurs de taille fixe

Grilles de cartes de produits où chaque carte a la même hauteur mais où les images ont des ratios différents. Verrouillez le conteneur, laissez l'image le remplir :

.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">

La taille est verrouillée avant que l'image ne se charge. Cela remplace également les images d'arrière-plan CSS. Les images d'arrière-plan ne peuvent pas être chargées en lazy loading, le preload scanner ne les trouve pas, et vous ne pouvez pas utiliser fetchpriority. Un <img> avec object-fit: cover vous donne tous ces contrôles.

Carrousels

Les transitions de diapositives qui animent left, width, ou margin déclenchent un recalcul de la mise en page. Parce que la lecture automatique n'est pas une entrée utilisateur, chaque décalage compte pour le CLS. Fixez le conteneur avec un ratio d'aspect fixe. Animez plutôt avec transform: translateX(). Les transformations s'exécutent sur le GPU et ne déclenchent jamais la mise en page.

Confinement pour les intégrations que vous ne pouvez pas contrôler

Emplacements publicitaires, widgets tiers, contenu généré par les utilisateurs. Vous ne contrôlez pas ce qu'ils rendent et vous ne pouvez pas les rogner. L'objectif réaliste est de minimiser le décalage, pas de l'éliminer.

Commencez par réserver de l'espace :

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

Le min-height gère le gros gain. Si la publicité se charge à 250px ou moins, pas de décalage. Si elle se charge à 300px, vous obtenez un décalage de 50px au lieu d'un décalage de 300px à partir de zéro. Cette différence compte.

contain: layout fait quelque chose de différent. Il n'empêche pas le conteneur de grandir. Il isole ce qui se passe à l'intérieur. Lorsque le réseau publicitaire injecte des scripts qui refont circuler leur propre contenu (redimensionnement d'iframes, injection de nouveaux éléments, recalcul de la mise en page interne), ces recalculs restent à l'intérieur du conteneur. Sans confinement, chaque refonte interne dans la publicité déclenche un recalcul de la mise en page pour l'ensemble de la page. Avec cela, le navigateur ignore tout ce qui se trouve à l'extérieur de la boîte. Cela rend la page plus réactive pendant le chargement des publicités.

contain: style empêche les compteurs CSS et autres effets secondaires de style de fuir. Une assurance bon marché.

Pour la valeur min-height, vérifiez les tailles de création les plus courantes de votre fournisseur publicitaire et choisissez celle qui couvre la majorité des impressions. Si 90 % de vos publicités font 250px et 10 % font 300px, réglez-le à 250px et acceptez le petit décalage occasionnel. Le régler à 300px signifie que 90 % des chargements de page ont 50px d'espace vide qui s'effondre lorsqu'une publicité plus petite se charge. Cet effondrement est aussi un layout shift.

Il n'y a pas de réponse parfaite pour les publicités. L'objectif est d'obtenir le plus petit décalage possible sur le plus grand nombre de chargements de page.

Comment trouver le CLS des images

Vous n'attraperez pas le CLS des images dans des conditions de navigation normales. Le cache de votre navigateur possède déjà les dimensions d'une visite précédente, donc le décalage ne se produit jamais. Pour voir ce que vos vrais utilisateurs voient, ouvrez les DevTools (F12), allez dans l'onglet Network, et cochez "Disable cache". Le cache n'est désactivé que lorsque les DevTools sont ouverts. Alternativement, utilisez une fenêtre de navigation privée.

Real User Monitoring

Commencez avec CoreDash ou un autre outil RUM. Les données d'attribution du CLS montrent exactement quels éléments se sont décalés. Accédez au CLS, regardez le tableau Element d'attribution. Filtrez pour image et vous obtenez chaque élément d'image affecté par les décalages de mise en page, classés par impact.

Chrome DevTools

Désactivez le cache dans l'onglet Network, limitez la connexion à Slow 4G, activez les captures d'écran, rechargez. Surveillez les sauts visuels. Ouvrez ensuite le panneau Performance et recherchez les entrées "Layout Shift". Cliquez sur un décalage pour voir le nœud, le score, et s'il y a eu une entrée utilisateur récente.

Core Web Vitals Visualizer

L'extension Core Web Vitals Visualizer met en évidence chaque décalage de mise en page avec une superposition colorée. J'utilise cela comme première étape avant d'ouvrir le panneau Performance. Rechargez avec l'extension active et vous voyez exactement ce qui a bougé.

Liste de contrôle rapide pour corriger le CLS

Élément Cause du CLS Correction
<img> Largeur/hauteur manquantes Ajoutez width et height ; utilisez height: auto; max-width: 100%; en CSS
<img> CSS width: auto écrasant les dimensions Supprimez width: auto ; ne conservez que height: auto
<img> Mauvaises valeurs de largeur/hauteur Utilisez les dimensions réelles en pixels de l'image
<video> Largeur/hauteur manquantes Ajoutez width et height correspondant à la résolution de la vidéo
<iframe> Par défaut 300x150 CSS aspect-ratio: 16 / 9; width: 100%; ou le modèle de façade
<picture> Différents ratios par source (bug Firefox) Définissez width/height sur chaque <source> ; ajoutez une solution de repli via une requête multimédia CSS
<img srcset> Ratios mixtes dans le srcset Même ratio pour toutes les sources ; définissez width/height sur la balise <img>
Lazy loading en JS Placeholder 1x1 avec un mauvais ratio Utilisez le loading="lazy" natif ou faites correspondre le ratio du placeholder
Carrousel Lecture automatique + transitions déclenchant la mise en page Conteneur avec un aspect-ratio fixe ; transform pour les transitions
SVG Aucune dimension intégrée Width/height sur l'<img> ou viewBox + CSS aspect-ratio
Emplacements publicitaires / intégrations Dimensions inconnues min-height + contain: layout style

Où en est le web sur le CLS des images

Les chiffres du Web Almanac 2025 :

  • 62 % des pages mobiles ont au moins une image non dimensionnée. En baisse par rapport à 66 % en 2024. Toujours la majorité.
  • 65 % des pages desktop ont des images non dimensionnées. En baisse par rapport à 69 %.
  • Au p75, une page desktop a 9 images non dimensionnées. Le mobile en a 8.
  • Hauteur médiane des images non dimensionnées : 111px sur desktop, 98px sur mobile. Assez pour décaler un paragraphe.
  • 72 % des origines desktop et 81 % des origines mobiles réussissent le CLS. En hausse par rapport à 62 % en 2021.

Le CLS s'est plus amélioré que tout autre Core Web Vital au cours des quatre dernières années. Les images non dimensionnées restent le principal contributeur. Corrigez ce seul problème et les décalages de mise en page disparaissent sur la plupart des sites.

Guides connexes

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 write the code, not the report.

I join your team for 1 to 2 sprints. I set up the monitoring and make sure your team keeps the metrics green after I leave.

Get in touch

Réponses aux questions sur le CLS des images et des médias

Pourquoi le width:auto sur les images cause-t-il un layout shift même lorsque les attributs width et height sont définis ?

Le ratio d'aspect interne du navigateur à partir des attributs width/height a la priorité CSS la plus basse. width: auto l'écrase, rendant les deux dimensions inconnues. L'image est rendue à 0x0 jusqu'à ce que le fichier se télécharge. Supprimez width: auto et ne conservez que height: auto; max-width: 100%;.

Dois-je également mettre width et height sur les éléments video et iframe ?

Oui pour les vidéos. Même mécanisme. Les iframes sont différents : ils ne calculent pas de ratio à partir des attributs et ont par défaut une taille de 300x150. Utilisez le CSS aspect-ratio ou le modèle de façade.

Comment puis-je empêcher le CLS avec l'élément picture lorsque les ratios d'aspect diffèrent par point de rupture ?

Définissez width et height sur chaque <source>. Chrome et Safari utilisent les bonnes dimensions. Firefox a un bug où il utilise toujours le fallback de l'<img>. Ajoutez des requêtes multimédias CSS avec le bon aspect-ratio par point de rupture comme solution de contournement.

Le lazy loading cause-t-il des layout shifts ?

Pas si l'image a des attributs de largeur et de hauteur. Mais le lazy loading des images au-dessus de la ligne de flottaison retarde le LCP sans aucun avantage. N'utilisez jamais loading="lazy" sur les images dans le viewport initial.

Pourquoi Lighthouse montre-t-il un bon CLS mais mes données de terrain montrent-elles des layout shifts ?

Lighthouse s'exécute sur un navigateur chaud avec un réseau rapide. Il ne détecte pas le problème de width: auto car il vérifie les attributs HTML, et non les styles CSS calculés. Vérifiez toujours le CLS avec des données de terrain provenant de CrUX ou d'un outil RUM comme CoreDash.

Comment les images et les médias causent le Layout Shift (et comment le corriger)Core Web Vitals Comment les images et les médias causent le Layout Shift (et comment le corriger)