TL;DR — Quick Summary
CLS measures how much visible content shifts unexpectedly during a page visit. Good CLS is ≤ 0.1 (unitless). Uses 'session windows' — shifts grouped into max 5-second windows, and the largest window becomes the CLS score. The easiest CWV to fix (add dimensions, reserve space) and has the highest pass rate (~72% of mobile origins).
What is Cumulative Layout Shift (CLS)?
Cumulative Layout Shift (CLS) is a Core Web Vitals metric that quantifies how much a page's visible content unexpectedly shifts during its entire lifespan. CLS is calculated using a 'session window' approach and two multiplied factors:
How CLS is Calculated:
Each individual layout shift is scored as: Impact Fraction × Distance Fraction
- •Impact Fraction — The percentage of the viewport affected by the shifting elements (union of the elements' before and after positions).
- •Distance Fraction — The greatest distance any element moved, as a fraction of the viewport dimension.
Shifts are grouped into session windows with a maximum duration of 5 seconds and no more than 1 second between consecutive shifts. The CLS score is the maximum session window score (not the sum of all shifts).
User-initiated shifts don't count: Layout shifts within 500ms of a user interaction (click, tap, keypress) are excluded. Only unexpected shifts penalize CLS.
This session window approach was adopted in 2021 to fix a problem with the original CLS calculation: long-lived pages (like SPAs or infinite-scroll pages) accumulated increasingly large CLS scores over time, which was unfair to sites users stayed on longest.
CLS Thresholds
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| CLS | ≤ 0.1 | 0.1 – 0.25 | > 0.25 |
Google evaluates the 75th percentile (p75) of real-user field data over a rolling 28-day window.
History & Evolution
CLS was introduced in May 2020 as part of the original Core Web Vitals trio.
Key milestones:
- •May 2020 — CLS announced as a Core Web Vital with cumulative (total sum) calculation.
- •June 2021 — CLS becomes a ranking signal. Simultaneously, the calculation changes from total sum to 'session windows' (max 5s duration, max 1s gap between shifts). This fixed the problem of long-lived pages accumulating unfairly high scores.
- •February 2022 — CLS ranking signal extends to desktop search.
- •2025–2026 — The 0.1 threshold and session window calculation remain unchanged.
The session window change was significant — many sites that previously had high CLS scores (especially SPAs and news sites with infinite scroll) saw dramatic improvements without any code changes, simply because the metric stopped accumulating shifts across the entire page visit.
How CLS is Measured
CLS is measured throughout the entire page lifespan using the Layout Instability API. The browser records every unexpected layout shift, groups them into session windows, and the maximum session window score becomes the page's CLS.
Field Data:
- •CrUX / PageSpeed Insights — Real-user CLS at p75
- •Google Search Console — CWV report
- •Web Vitals JS library — Custom RUM collection
Lab Data:
- •Lighthouse — CLS carries 25% of performance score (but only captures load-time CLS, not interaction-triggered shifts)
- •Chrome DevTools Performance panel — Shows every layout shift with visual highlighting
- •WebPageTest — Filmstrip view shows shifts visually
Important: Lighthouse only captures CLS during page load. Real-user CLS can be worse because it includes shifts triggered by scrolling, lazy loading, or delayed content injection. Always compare lab CLS with field CLS.
Key rule: Field data (CrUX) determines Google rankings. Lab data (Lighthouse, WebPageTest) is for debugging and iteration.
Common Causes of Poor CLS Scores
The most common causes of poor CLS:
- 1Images without width/height — Browser can't reserve space before the image loads, so content below shifts down when it appears.
- 2Ads, embeds, and iframes without reserved space — Ad slots that resize after loading push content around.
- 3Dynamically injected content — Cookie banners, notification bars, and promotional strips inserted above existing content.
- 4Web fonts causing FOUT/FOIT — Custom fonts that load after system fonts cause text to reflow (different letter spacing, line heights).
- 5Late-loading CSS — Stylesheets that change element dimensions after initial render.
- 6Images loaded lazily without placeholders — Lazy-loaded images that don't have aspect-ratio containers.
- 7Animations triggering layout — Animating width, height, top, left instead of transform and opacity.
Frequently Asked Questions
For step-by-step optimization, platform-specific fixes, code examples, and case studies, read our full guide:
The Ultimate Guide to Core Web Vitals: How to Pass All Metrics & Boost Rankings in 2026Struggling with CLS?
Request a free speed audit and we'll identify exactly what's holding your scores back.