Cumulative Layout Shift (CLS)
Cumulative Layout Shift, or CLS, is one of Google's three Core Web Vitals. It measures visual stability: how much the content of a page moves around unexpectedly while it loads and while the visitor uses it. Everyone has tried to tap a button only for an ad or image to load and push it out of reach at the last moment. CLS puts a number on exactly that frustration, and a low score means the layout stays where the visitor expects it.
What CLS measures
CLS looks at unexpected layout shifts, moments when a visible element changes position from one rendered frame to the next without the visitor causing it. Each shift is given a layout shift score, calculated as the impact fraction multiplied by the distance fraction: how much of the viewport was affected, times how far the elements moved. The more of the screen that jumps and the further it travels, the higher the score.
The metric does not simply add up every shift on the page. It records the largest burst of shifts that happen close together, known as a session window, and reports that worst burst as your CLS. This matters because a long page with occasional small shifts is judged on its worst moment, not penalised endlessly for its length. A session window opens with the first shift, extends as long as new shifts keep occurring within one second of each other, and caps at five seconds; the highest-scoring window becomes your CLS.
Crucially, only unexpected shifts count. When an element moves within 500 milliseconds of a user interaction, such as expanding an accordion after a click, the shift is treated as expected and excluded. CLS is about movement the visitor did not ask for.
How the layout shift score is calculated
A quick example makes the formula concrete. Suppose a block of text fills half the visible screen and, when an image loads above it, moves down by a quarter of the viewport height. The impact fraction is 0.5, because half the viewport was affected, and the distance fraction is 0.25, because the content moved a quarter of the screen. The layout shift score is 0.5 x 0.25 = 0.125, already past the 0.1 good threshold from a single shift. Broken down this way, it is clear why one large movement of prominent content matters far more than several tiny ones near the edge of the screen.
What is a good CLS score
CLS is a unitless number, and Google defines three bands measured at the 75th percentile of real page loads:
- Good: 0.1 or less
- Needs improvement: between 0.1 and 0.25
- Poor: more than 0.25
Because it is measured at the 75th percentile across mobile and desktop, three out of four visits must stay below the target. A score that looks fine on a fast desktop can still fail if mobile visitors see ads and images shift on slower connections.
How CLS is measured: lab and field
CLS is the Core Web Vital where lab and field data diverge the most, and understanding why prevents a lot of confusion. Lab tools such as Lighthouse only measure shifts during the initial page load in a controlled environment. Field data from the Chrome UX Report measures the entire time a real visitor has the page open, including shifts that happen while scrolling, when lazy-loaded content arrives, or when an interaction triggers new layout. As a result, a page can show a near-perfect CLS in the lab and a poor one in the field. Always trust the field data for the real picture.
You can watch shifts happen in the browser with the Performance API, filtering out the expected ones:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
console.log('layout shift:', entry.value, entry.sources);
}
}
}).observe({ type: 'layout-shift', buffered: true });
The sources property points to the exact elements that moved, which is the fastest way to find the culprit.
What causes layout shifts
Most CLS comes from a short list of recurring causes:
- Images and video without dimensions. When the browser does not know an element's size in advance, it reserves no space, then reflows the page once the file loads.
- Ads, embeds and iframes. Third-party content whose height is unknown until it arrives pushes everything below it down.
- Dynamically injected content. Banners, notices or related-content blocks inserted above existing content shift everything beneath them.
- Web fonts. A late-loading font can swap in at a different size to the fallback, reflowing the text around it.
- Animations that trigger layout. Animating properties such as top, height or margin forces the browser to recompute positions on every frame.
How to fix CLS
1. Always set dimensions on images and video
Give every image and video explicit width and height attributes, or a CSS aspect-ratio, so the browser reserves the correct space before the file arrives:
<img src="photo.jpg" width="800" height="600" alt="Product">
/* responsive: keep the ratio while the width flexes */
img { aspect-ratio: 4 / 3; width: 100%; height: auto; }
This is the single most common CLS fix, and it overlaps with the work in properly size images and defer offscreen images, where correct dimensions matter for loading too.
2. Reserve space for ads, embeds and iframes
Set a minimum height on any container that will hold an ad or third-party embed, sized to the most common creative, so the slot does not collapse and then expand. If a slot may go unfilled, style it so the reserved space still looks intentional rather than leaving a jarring gap.
3. Never insert content above existing content
Avoid injecting banners, cookie notices or promotional bars above content the visitor is already reading, unless it is in direct response to their interaction. If you must show such elements, reserve space for them from the start or overlay them rather than pushing the layout down.
4. Stabilise web fonts
Reduce font-driven shifts by adding font-display: swap so text is visible immediately, preloading the font used above the fold, and choosing a fallback whose metrics are close to the web font so the swap barely moves anything. This connects to the font handling covered under eliminate render-blocking resources. The CSS descriptors size-adjust, ascent-override and descent-override let you tune the fallback font to match the web font's metrics almost exactly, so the eventual swap causes little or no visible shift.
5. Animate with transform, not layout properties
When you animate, use transform and opacity, which the browser can composite without recalculating layout. Animating top, left, width or height forces reflow on every frame and can register as layout shift.
6. Reduce CLS in WordPress
Most CLS on WordPress comes from themes, page builders and plugins. Make sure images added through the editor keep their width and height attributes, reserve space for ad and embed blocks, and avoid plugins that inject banners or related-content boxes above the article. A performance plugin can preload fonts and add missing image dimensions, but test afterwards, since some lazy-loading settings introduce shifts of their own.
How to verify your CLS
Chrome DevTools can highlight shifting regions: enable Layout Shift Regions in the Rendering panel and blue flashes mark every shift as it happens. The Performance panel records each shift with the element responsible. Re-run PageSpeed Insights for the lab score, but remember it only covers load, so confirm the real improvement in the field data of the Chrome UX Report over its trailing 28-day window. Test on mobile with throttling, and scroll the whole page, since many shifts only appear as lazy-loaded content arrives further down. As with the other Core Web Vitals, field CLS is reported per URL when a page has enough traffic and otherwise rolls up to an origin-level average, so a new page can show the whole site's stability until it gathers its own sample.
CLS and the other Core Web Vitals
CLS is one of three Core Web Vitals alongside Largest Contentful Paint, which measures loading speed, and Interaction to Next Paint, which measures responsiveness. They interact: setting explicit dimensions on the main image improves both CLS and Largest Contentful Paint, and reserving space for content keeps the page stable while other optimizations load. Fix CLS as its own goal, but check that speed changes have not introduced new shifts, and that stability work has not delayed the main content.
Frequently asked questions
What is a good CLS score?
0.1 or less at the 75th percentile of real users is good. Between 0.1 and 0.25 needs improvement, and more than 0.25 is poor. CLS is a unitless number.
What causes a high CLS?
The usual causes are images and video without dimensions, ads and embeds without reserved space, content injected above existing content, late-loading web fonts, and animations of layout properties.
Why is my CLS low in the lab but high in the field?
Lab tools only measure shifts during page load, while field data measures the whole time a visitor uses the page, including shifts from scrolling and lazy-loaded content. The field data is the one Google uses.
How do I fix layout shift from images?
Give every image an explicit width and height, or a CSS aspect-ratio, so the browser reserves the correct space before the image loads and does not reflow the page.
How do I stop ads from causing layout shift?
Reserve space for each ad slot with a minimum height sized to the most common creative, so the slot does not collapse and then expand when the ad arrives.
Is CLS a Google ranking factor?
Yes. CLS is one of the three Core Web Vitals, which are part of Google's page experience signals and are assessed on real-user field data.
Test your site
Run a free scan to see whether this applies to your pages, on mobile and desktop, with lab and field data side by side.
Run a free test