Lazy loading image layout shift bugs happen when images load after text has already painted and the browser did not reserve the correct space.
CSS Layout Shift Fix
Why Does Lazy Loading Cause Image Layout Shift?
Lazy loading image layout shift happens when the page renders before an image has a stable box. The browser paints the text, cards, or product list first. Then the image loads, claims space, and pushes everything around.
Lazy loading is not the enemy. The problem is lazy loading without reserved dimensions. If the image does not have width, height, aspect-ratio, or a stable placeholder, the browser has to guess how much space the image will need.
- lazy loading
- layout shift
- width and height
- aspect-ratio
Test the empty image box
Disable the image request or throttle the network and reload the page. If the layout has no stable box where the image should be, the image will probably shift the content when it finally appears.
Related: Try this in the FrontFixer Live Inspector.
Open Live Inspector→What the bug looks like
Text, cards, buttons, or product rows jump after a lazy image finishes loading.
Why it happens
The browser did not know the image height before the file arrived.
What usually fixes it
Reserve media space with real dimensions, aspect ratio, or a matching placeholder.
Why lazy loading can move the page
Lazy loading delays the image request until the image is close to the viewport. That can improve performance, but the layout still needs to know the image’s future size. If the browser cannot reserve that space, it renders the surrounding content first.
When the image finally appears, the page must recalculate. The image box grows, the text below moves, buttons shift, cards change height, and the user sees a jump. This is the lazy loading image layout shift problem.
The clean fix is not to disable lazy loading everywhere. The clean fix is to give every lazy image a predictable footprint before it loads. That footprint can come from HTML attributes, CSS ratio wrappers, stable skeletons, or a component-level media shell.
The lazy image has no reserved dimensions
This is the most common lazy image shift. The image tag has loading="lazy", but no width, height, or ratio. The page lays out as if the image takes little or no space, then expands when the file loads.
Broken code
No reserved size<img
src="card.jpg"
loading="lazy"
alt="Product preview">
Broken visual result
Correct code
Dimensions reserved<img
src="card.jpg"
loading="lazy"
width="800"
height="450"
alt="Product preview">
Fixed visual result
before loading
The placeholder does not match the final image shape
A skeleton is helpful only if it reserves the same space as the final media. If the placeholder is short and the lazy image is tall, the layout still shifts when the real image replaces it.
Broken code
Skeleton too short.image-placeholder {
height: 60px;
}
.image-placeholder img {
width: 100%;
height: auto;
}
Broken visual result
Correct code
Skeleton matches ratio.image-placeholder {
aspect-ratio: 4 / 3;
overflow: hidden;
}
.image-placeholder img {
width: 100%;
height: 100%;
object-fit: cover;
}
Fixed visual result
Responsive sources use different ratios
Art-directed images can change shape between desktop and mobile. If the reserved space is based on the desktop source but the mobile source has a different ratio, the final image can still shift the layout.
Broken code
Sources disagree<picture>
<source media="(max-width:600px)" srcset="portrait.jpg">
<img src="landscape.jpg" loading="lazy" width="1200" height="675" alt="">
</picture>
Broken visual result
Correct code
Ratio controlled per layout.art-media {
aspect-ratio: 16 / 9;
}
@media (max-width:600px) {
.art-media {
aspect-ratio: 1 / 1;
}
}
Fixed visual result
Lazy thumbnails inside a feed change row height
Feeds, search results, and product lists often shift because each row starts with text only. When the lazy thumbnail loads, the row height changes and every item below it moves.
Broken code
Rows wait for image height<div class="feed-row">
<img src="thumb.jpg" loading="lazy" alt="">
<p>Search result text...</p>
</div>
Broken visual result
Correct code
Feed media reserves space.feed-thumb {
aspect-ratio: 1 / 1;
overflow: hidden;
}
.feed-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
Fixed visual result
Three production-minded lazy image stability patterns
Premium lazy image systems reserve space for the final media, match placeholders to final ratios, and use stable component wrappers so lazy loading improves speed without making the page feel unstable.
Premium code example 1
Editorial image shell.article-media {
aspect-ratio: 16 / 9;
overflow: hidden;
border-radius: 20px;
background: #f3f4f6;
}
.article-media img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
Premium visual result 1
The title, hero image, and related cards keep the same rhythm while the image loads.
Premium code example 2
Product feed thumbnails.product-thumb {
aspect-ratio: 4 / 5;
overflow: hidden;
background: #f3f4f6;
}
.product-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
}
Premium visual result 2
Each product owns a 4/5 media slot before the image file arrives.
Premium code example 3
Feed row media shell.feed-row {
display: grid;
grid-template-columns: 96px minmax(0, 1fr);
gap: 16px;
}
.feed-thumb {
aspect-ratio: 1 / 1;
overflow: hidden;
}
Premium visual result 3
Rows reserve thumbnails before lazy images enter the viewport.
Fast practical rule
Lazy loading should delay the download, not delay the layout size. Give every lazy image a stable box with width and height, an aspect-ratio wrapper, or a placeholder that exactly matches the final media shape.
Debug checklist
- Check whether the lazy image has real
widthandheightattributes. - Inspect whether the media wrapper has a stable
aspect-ratio. - Compare the placeholder height with the final image height.
- Throttle the network and watch the page before images load.
- Check whether mobile and desktop image sources use different ratios.
- Reserve thumbnail space in feeds, grids, cards, and search results.
- Use
object-fit:coverwhen the image must fill a reserved shell. - Avoid lazy loading above-the-fold hero images that are critical to first paint.
When lazy loading is still the right choice
Lazy loading is still useful for below-the-fold images, long article pages, product grids, galleries, and feeds. The problem is not the lazy strategy. The problem is using it without giving the browser enough information to reserve space.
Above-the-fold hero images are different. If an image is critical to the first visible layout, eager loading may be better. But even eager images should still have width, height, or a stable wrapper so the layout does not depend on the network.
A practical rule is to keep the first visible hero, logo, and key product image stable and quick. Images farther down the page can load lazily as long as their slots are already measured. That balance protects both perceived speed and visual stability.
The worst version is a page that looks fast for one second and then rearranges itself while the user is reading. A stable lazy image system feels calmer: the content appears, the empty media slots already have the correct shape, and the files fade in without moving anything.
Why this fix is different from missing width and height
Missing width and height is one major cause of image layout shift, but this fix is focused on lazy loading behavior. It covers the moment when the image is intentionally delayed and the page still needs a stable media footprint before the file arrives.
That keeps this article separate from the broader missing-dimensions fix. Here, the debugging question is: “Does lazy loading delay only the image request, or does it also accidentally delay the layout space?”
If the layout space is delayed, the user experiences a jump. If only the file request is delayed, the user experiences a stable page with images arriving smoothly. That distinction is the heart of this fix.
Final takeaway
Lazy loading image layout shift happens because the image file is delayed but the layout still needs to know the image’s future size. If that space is not reserved, the content below moves when the image arrives.
Keep lazy loading for the right images, but always reserve the final media footprint. Use width and height attributes, aspect-ratio wrappers, matching skeletons, and feed thumbnails with stable dimensions. That gives you performance without a jumpy page.