CLS (Cumulative Layout Shift)
How much visible layout shifts during a page's lifetime.
CLS — Cumulative Layout Shift — is the Core Web Vitals metric that quantifies how much visible page content unexpectedly moves during a page's lifetime, capturing the frustrating experience of trying to tap a button or read text just as the layout shifts beneath it.
It is calculated from the impact fraction — how much of the viewport was affected by a shift — multiplied by the distance fraction — how far the affected content moved — summed across the worst burst of shifts within any five-second window in the session, rather than every shift added together across the entire page lifetime.
The official 'good' threshold is a p75 CLS score under 0.1; between 0.1 and 0.25 is 'needs improvement'; above 0.25 is 'poor'. Because the score is unitless and multiplicative, even small movements across a large portion of the viewport, or large movements of a small element, can push a page into a failing band.
The three most common causes are images or embeds without explicit width and height attributes (so the browser reserves no space until the resource loads), web fonts that swap in late and reflow surrounding text, and dynamically-injected content — ads, cookie banners, promotional bars — that pushes existing content down after the initial layout has already settled.
How CLS is calculated in practice
Every time a visible element moves between two rendered frames without being triggered by a user interaction (a user-initiated resize or an intentional animation triggered by a click is generally excluded from the calculation), the browser records a layout shift score for that event equal to impact fraction times distance fraction.
Rather than summing every shift across the whole page lifetime — which would unfairly punish long-lived single-page apps — CLS uses a 'session window' methodology: shifts are grouped into windows with gaps of less than one second and a maximum duration of five seconds, and the single largest window's cumulative score becomes the page's CLS.
Why CLS matters more in the AI-search era
As with the other Vitals, CLS's ranking weight is secondary to its direct effect on conversion: a visitor who taps a 'call now' or 'get a quote' button just as an ad or promotional element shifts the page, missing the tap or hitting the wrong element, is a lost lead regardless of how the page ranked to get them there. In a search landscape where fewer, higher-intent clicks make it through AI Overviews, protecting that conversion moment matters more, not less.
How to diagnose CLS issues
Use Search Console's Core Web Vitals report or CrUX to confirm CLS is genuinely failing in the field for a given URL group, then use Chrome DevTools' Performance panel or the Layout Shift Regions overlay to visually identify exactly which elements are shifting and when during the page load.
PageSpeed Insights lists the specific DOM elements contributing most to a page's lab-measured CLS score, which is a fast way to triage the largest offenders before a full manual review.
Common causes of CLS failures
Images and video embeds published without explicit `width` and `height` attributes (or a CSS `aspect-ratio`) are the most common cause — the browser has no way to reserve the correct space until the resource has actually loaded and reports its dimensions.
Web fonts loaded without a `font-display` strategy or preloading can cause a visible text swap (FOIT or FOUT) that reflows surrounding content once the custom font finally loads.
Dynamically injected content — ads, cookie-consent banners, 'sign up' promotional bars, and lazy-loaded embeds without reserved space — routinely pushes existing, already-rendered content down the page after the user has started interacting with it.
- Images/embeds with no explicit width/height or aspect-ratio.
- Web fonts without font-display or preload causing text reflow.
- Ads, banners, or cookie notices injected without reserved space.
- Content inserted above existing content in response to an async data fetch.
A step-by-step CLS fix process
Add explicit `width` and `height` attributes (or a CSS `aspect-ratio`) to every image, video, and iframe embed sitewide so the browser reserves correct space before the resource loads.
Set a `font-display` strategy — `optional` for non-critical fonts, or preload the critical font file — to prevent late text reflow, and consider matching fallback and custom font metrics to minimise the visible size difference during any swap that does occur.
Reserve fixed space for ads, cookie banners, and promotional bars using CSS placeholders sized to their expected content, rather than letting them inject and push the page down after render.
Audit any content inserted above existing page content in response to asynchronous data (for example, a personalisation banner that appears after a fetch completes) and either move it below the fold or reserve its space upfront.
Re-test using field data over a 28-day CrUX window, since CLS in particular can vary meaningfully between lab tests and real-world sessions with slower connections and more third-party interference.
CLS for local Austin-area service business sites
Local sites running on page builders or marketing platforms frequently accumulate cookie banners, chat-widget launchers, and promotional pop-ups stacked on top of each other, each individually reasonable but collectively a common source of CLS failure. Reviewing the full stack of injected third-party elements together, rather than one at a time, usually surfaces the real cause faster than isolated fixes.
How CLS relates to LCP, INP, and page builders
CLS is the stability component of Core Web Vitals, distinct from LCP's speed focus and INP's responsiveness focus, and a page can fail any one independently of the others. Page-builder and no-code platforms are disproportionately prone to CLS issues because they frequently inject dynamic elements — pop-ups, widgets, personalisation blocks — without giving developers granular control over reserved space.
CLS thresholds and common contributors
| Good | ≤ 0.1 | Passes the Core Web Vitals threshold at p75. |
|---|---|---|
| Needs improvement | 0.1–0.25 | Often caused by one or two unmanaged dynamic elements. |
| Poor | > 0.25 | Usually multiple compounding causes across the page. |
| Typical single ad-slot contribution | 0.05–0.15 | If injected without reserved space above existing content. |
Frequently asked questions
- What is a good CLS score?
- 0.1 or under, measured at the 75th percentile of real user sessions in the field. Between 0.1 and 0.25 is 'needs improvement'; above 0.25 is classified 'poor' under Google's Core Web Vitals thresholds.
- What usually causes layout shift?
- Most commonly images or embeds without explicit width and height attributes, web fonts that reflow text when they load late, and dynamically-injected content like ads, cookie banners, or promotional bars that push existing content down after render.
- Does a pop-up always cause a CLS problem?
- Only if it's injected in a way that pushes other visible content or reserves no space beforehand. A pop-up that overlays the page without shifting existing layout, or that has its space reserved in advance, doesn't count toward CLS.
- How do I find which element is causing my CLS score?
- PageSpeed Insights lists the specific DOM elements contributing most to a page's CLS in its diagnostics section. Chrome DevTools' Performance panel and Layout Shift overlay let you visually pinpoint exactly when and where a shift happens.
- Can fonts really cause a CLS failure?
- Yes. A web font that loads after the page has already rendered fallback text at a different size or width causes a visible reflow when it swaps in — this is a well-documented, common contributor, fixable with a font-display strategy or preloading.
A local clinic's site had a CLS of 0.28, driven by a promotional appointment-booking bar that injected above the header after a one-second delay. Reserving fixed space for the bar in the initial layout brought CLS down to 0.04.
Need this applied to your site?
We turn concepts like these into shipped work every week.
