You know the feeling from other people’s websites. You are halfway through a sentence and the text drops out of view. You reach for a link and an advert slides into its place. On your own site you might not notice it at all, because your browser has everything cached and the page settles instantly. Your visitors are not so lucky, and Google’s CLS figure is how you find out.
Learning how to fix cumulative layout shift is mostly a matter of going cause by cause. Most CLS issues on small business sites come from a short list of culprits, and once you can see the shift happening, the fix is usually clear. The first job is making it visible.
What CLS is actually adding up
CLS is the visual stability metric among the three Core Web Vitals (the introduction to the three Core Web Vitals covers the other two). A layout shift happens when something already on screen moves position without the visitor asking it to. Each shift gets a score based on how much of the screen moved and how far it travelled.
Shifts that happen close together are grouped into a burst, and CLS reports the worst burst during the visit. Google treats 0.1 or less as good, at the 75th percentile of visits.
Two details save a lot of wasted effort:
- Movement the visitor caused does not count. If someone taps “Read more” and a section expands, shifts within a short window after that tap are excluded.
- Animations using CSS transforms do not count. A banner that slides in using a transform does not push other content around in the layout, so it does not register. A banner that slides in by changing its height or top margin does.
Step one: see the shift for yourself
Because shifts often depend on timing, they can be hard to spot by eye on a fast connection. Slow things down and highlight them.
- PageSpeed Insights. Run the page and look in the diagnostics for the layout shift section. It lists the elements that moved most and, where it can tell, what caused them, such as an image without dimensions or a web font.
- Chrome DevTools, Rendering panel. Open DevTools, press the menu for more tools and open Rendering. Tick Layout Shift Regions. Reload the page and every shift flashes with a coloured overlay as it happens.
- Throttle the network. In the Network panel, choose a slower connection preset. Late-arriving images, ads and fonts now arrive late enough for you to watch the page jump.
- Use a phone, in a private tab. Many shifts only appear on mobile layouts, and only for first-time visitors who have not dismissed the cookie banner.
Write down what moved and what appeared just before it moved. That second part is the cause.
Images and videos without dimensions
What you see: text loads first, then gets pushed down as an image appears above it.
Why: if an image has no width and height attributes (or a CSS aspect ratio), the browser has no idea how tall it will be until the file arrives. It reserves zero space, then makes room when the image loads.
Fix: make sure every image in your content carries width and height. WordPress adds them to images inserted through the editor, but they go missing with images added by hand in HTML, by some page-builder widgets, by older themes, and by plugins that rewrite image tags. Modern browsers use those attributes to work out the aspect ratio, so the image can still be responsive. For video and iframe embeds, give the container a fixed aspect ratio in CSS.
Ads, embeds and widgets that arrive late
What you see: a gap appears in the middle of an article, or the page jumps when a map, review widget, social feed or ad finishes loading.
Why: these are loaded by scripts after the page itself, and their height is unknown until they render. Ad slots are a frequent offender because the ad served may be a different size each time.
Fix: reserve space. Give each ad slot or embed container a minimum height that matches its most common size. If an ad sometimes does not fill, it is better to leave a reserved blank area than to collapse it and drag the content up. Placing ad slots lower on the page, away from the first screen, also reduces their effect. For third-party widgets, check whether the plugin offers a placeholder or fixed-height option; some do.
Web fonts swapping in
What you see: the text appears in one font, then flickers into another and the lines rewrap, pushing everything below up or down.
Why: the fallback font shown first and the web font that replaces it have different letter widths and line heights. When the swap happens, paragraphs change length.
Fix: use fewer font files, load the important ones early, and choose a fallback font whose size is close to the web font. The detail of how browsers handle text while fonts download, and the trade-off between showing text early and avoiding the swap, is the subject of our post on font-display and invisible text.
Banners and bars injected at the top
What you see: the whole page drops down a strip after loading. A promotional bar, “free shipping over” notice, app download prompt, or announcement appears above the header.
Why: a plugin or script inserts the bar after the page has rendered, and everything below has to move to make room.
Fix: either render the bar in the page HTML from the start so its space is there from the first paint, or overlay it without moving content (fixed to the bottom or top of the screen, on top of the page rather than pushing it). Promotional bars controlled by a JavaScript timer are a frequent hidden source of CLS.
Cookie and consent notices
What you see: on a first visit, the consent notice appears and pushes the page content, or the page jumps when the notice is dismissed.
Why: some consent tools insert their notice into the normal page flow rather than floating above it. Because returning visitors have already dismissed it, the shift only shows up for new visitors, and on many small business sites new visitors make up a large part of the field data.
Fix: configure the notice as an overlay or a fixed bar that sits on top of the page. Most consent plugins have a layout setting for this. Test in a private window each time, since your own browser remembers your choice.
Sliders, carousels and tabs
What you see: the hero area starts short, then expands when the slider script runs, or each slide is a slightly different height and the page bounces as it rotates.
Why: many sliders render nothing (or all slides stacked) until their script initialises, then resize the container. Auto-rotating slides of different heights move content below them without any visitor action.
Fix: set a fixed height or aspect ratio for the slider container, and make all slides the same size. Sliders have a wider set of speed costs beyond layout shift; whether image sliders are worth their weight looks at those, and at simpler alternatives.
Content loaded after the page by JavaScript
Related posts, “you might also like” product strips, recently viewed lists, live stock counters and price updates fetched after load can all appear above existing content and push it down. The cure is the same idea every time: give the container its final size from the start, or load it below the area the visitor is looking at.
How to fix cumulative layout shift and confirm it stayed fixed
After each change, reload with Layout Shift Regions on and a throttled network, and confirm the flash has gone. Run PageSpeed Insights a few times on the same page and check the layout shift diagnostics no longer list the element you fixed.
Then look at the wider picture. Search Console’s Core Web Vitals report groups pages with similar CLS issues, so one template fix can clear a whole group. The walkthrough of how to read the Core Web Vitals report in Search Console covers starting validation and why the data takes weeks to update.
CLS is the most visual of the three metrics, but stability is only one part of a fast, pleasant page. The full guide to website speed puts it alongside loading, scripts and hosting.
Mistakes when fixing CLS issues
- Testing only as a logged-in admin. The admin bar, cached assets and dismissed banners all hide what new visitors see.
- Fixing desktop and forgetting mobile. Stacked mobile layouts change which elements are above others, so the culprit can be different.
- Collapsing empty ad slots. It looks tidier but causes a shift whenever an ad does not fill.
- Lazy-loading content near the top without reserved space. Anything that loads in the first screen should have its height set.
Frequently asked questions
Why is my CLS poor in field data but zero in Lighthouse?
Lighthouse only measures shifts during the initial page load in a test environment. Real visitors scroll, wait for ads to fill, see cookie notices and trigger late widgets, and shifts during that time count in the field. A low lab score with a poor field score usually means the shift happens later in the visit or only for certain visitors.
Does a sticky header cause layout shift?
A header fixed in place with CSS does not usually cause layout shift. Problems arise when the header changes height as you scroll, or switches from normal to fixed position in a way that pulls the content up. If your theme shrinks the header on scroll, check it with layout shift highlighting turned on.
Does lazy loading cause layout shift?
Not by itself. A lazy-loaded image with width and height set has its space reserved, so nothing moves when it arrives. Shifts happen when lazy-loaded images, embeds or sections have no reserved size, or when a plugin swaps in a placeholder of the wrong height. Check that placeholders match the final dimensions.
Layout shift from a theme or builder template is often a small change in the right file. CLS is one of the three Core Web Vitals our website speed optimisation help covers, and nothing is changed until you have seen the fix list.
Next in this series: Reading the Core Web Vitals Report in Search Console