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

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
Table of Contents!
- Comment les images et les médias causent le Layout Shift (et comment le corriger)
- Le navigateur ne sait pas quelle est la taille de votre image
- Comment width et height préviennent le layout shift
- Les choses qui annulent la correction
- Quand CSS aspect-ratio est le meilleur choix
- Vidéos, iframes, et SVGs
- Images responsives
- Conteneurs fixes, carrousels, et confinement
- Comment trouver le CLS des images
- Liste de contrôle rapide pour corriger le CLS
- Où en est le web sur le CLS des images
- Guides connexes
- Réponses aux questions sur le CLS des images et des médias
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
- Qu'est-ce que le Cumulative Layout Shift (CLS) : Le guide complet. Formule, seuils, fenêtres de session, et toutes les causes de CLS au-delà des images.
- Trouver et corriger les problèmes de CLS : Diagnostics étape par étape avec des données RUM, les DevTools, et des corrections pour chaque cause.
- Corriger le layout shift causé par les images auto-dimensionnées : La procédure complète pour le
width: auto. - Optimiser les images pour les Core Web Vitals : Préchargement, images responsives, formats, priorisation.
- Layout shift causé par les transitions CSS : Comment les animations déclenchant la mise en page causent le CLS.
- Intégrations YouTube parfaites : Le modèle de façade pour un CLS nul.
- Google Maps 100% PageSpeed : Même approche de façade pour Maps.
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 touchRé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.

