Cumulative Layout Shift (CLS)
Cumulative Layout Shift scores how much visible content moves unexpectedly while a page is open. It has no unit. A good CLS is 0.1 or less, at the 75th percentile of page loads.
It's the one Core Web VitalGoogle’s three headline UX metrics: LCP (load), INP (responsiveness), CLS (stability). that measures annoyance instead of speed. A page can load in 800 ms and still be miserable, because the link you aimed at slid down the screen first.
The name is also misleading. CLS is no longer a running total, and that changes how you fix it.
The thresholds
| CLS | Verdict |
|---|---|
| 0.1 or less | Good |
| 0.1 to 0.25 | Needs improvement |
| More than 0.25 | Poor |
Measure at the 75th percentile of page loads, and segment mobile and desktop separately. The two layouts break in different places.
How is CLS calculated?
A layout shift happens when a visible element changes position between two rendered frames. The browser scores each one:
layout shift score = impact fraction × distance fraction
- Impact fraction — the share of the viewport covered by the moving elements, across both frames.
- Distance fraction — the furthest any element moved, divided by the larger viewport dimension.
Google's worked example gives an impact fraction of 0.75 and a distance fraction of 0.25. That is a layout shift score of 0.1875. So the number is a fraction of your screen, not a duration — which is why a CLS has no unit to put after it.
CLS is not cumulative
The original metric added up every shift for the whole life of the page. An infinite scroller could not win. Google revised the definition, and it reached Chrome's web tooling on 2 June 2021.
The browser now groups shifts into session windows. A window opens at the first shift and keeps extending while each gap stays under 1 second. No window runs longer than 5 seconds. CLS is the score of the worst window — not the total.
That is a different repair job than the name suggests. Find the single worst burst and remove it. Ten small shifts spread across a long article can cost you nothing, while one banner that pushes the body down costs you everything.
Which shifts count?
Only the unexpected ones. A shift within 500 milliseconds of a tap, click or key
press carries the hadRecentInput flag, and it's excluded. Opening an accordion is
free. The same movement with nobody touching anything is scored against you.
What causes layout shift?
| Cause | Fix |
|---|---|
| Images and videos with no dimensions | Set width and height attributes, or reserve the box with CSS aspect-ratio |
| Ads, embeds and late-loaded content | Reserve the space in the first layout, or overlay it outside the document flow |
| Web fonts swapping in | font-display: optional, preload the file, and match the fallback metrics |
Animated top, left or box-shadow |
Animate transform instead |
Images are the usual culprit, and the cheapest to fix. Modern browsers derive a
default aspect ratio from the width and height attributes. The box is then
reserved before a single byte of the image arrives.
Why is my CLS 0 in Lighthouse but bad in Search Console?
Because a lab run only sees part of the problem. Google is blunt about it. Lab tools load a page in a synthetic environment. They can only measure the layout shifts that happen during load. Real visitors keep the page open, and CLS keeps counting for the whole life of that page.
We can put a number on how little that leaves. Our three warm example report pages each keep the last 25 audits. Between 3 July and 13 August 2026 that's 131 completed mobile runs, all on Lighthouse 12.8.2, from Frankfurt and Washington. CLS was exactly 0 in 110 of them. The worst value in the whole set is 0.002, about fifty times below the "good" threshold.
The slowest page on that rig makes the point on its own. vercel.com, 6 August 2026, measured from both regions: an LCP of 12.0 seconds from Frankfurt and 13.0 from Washington, for performance scores of 31 and 33. Its CLS was 0 from both.
So we'll say it plainly: a lab CLS is the least informative number in a Lighthouse report. It's worth 25 of the 100 performance points, level with LCPTime until the largest thing in view (hero image, headline) has painted.. Every one of those 131 runs took the full 25, including the page that scored 31. Read a lab CLS of 0 as "nothing moved during load". Never read it as "this page is stable".
The field number is the one Google grades you on. It reaches you through the Chrome UX Report and Search Console, over a rolling 28-day window. So a CLS fix you ship today needs about four weeks to reach full weight there.
What a Lightscore result gives you
Every completed result carries a cls value taken straight from the Lighthouse
audit, next to lcp_ms, tbt_ms and the rest. We also hand back the raw Lighthouse
JSON. That's where the useful part is. The layout-shifts audit names each element
that moved, with its own score.
That 0.002 worst case was
a wikipedia.org run,
and the JSON splits it across exactly two elements: img.central-featured-logo at
0.00165 and a div.styled-select in the search form at 0.00037. That's the level a
fix starts at — a selector, not a number.
We can't give you a field CLS, and no lab tool can. A pinned lab run is good for one thing here: it catches a shift you just shipped, before your visitors meet it. A lab CLS pinned at 0 across many runs is at least a stable baseline. The performance score around it wanders by a few points on its own. So if CLS moves from 0 to 0.3 between two runs of the same version, your layout changed, and the JSON names what moved.
what’s this
The small set of field metrics Google treats as a ranking input and reports in Search Console. We measure their lab equivalents here — real-user field data (CrUX) is a separate signal. TBT is the lab stand-in for INP, not a Core Web Vital itself.
Common questions
What is a good CLS score?
0.1 or less, at the 75th percentile of page loads. Between 0.1 and 0.25 needs improvement, and anything above 0.25 is poor. Measure mobile and desktop separately, because the layouts shift differently.
Is CLS cumulative?
Not any more. Google revised the definition, and it reached Chrome's web tooling on 2 June 2021. The browser groups layout shifts into session windows, and CLS reports the highest-scoring window rather than the sum of every shift. A window ends after a gap of 1 second with no shifts, and no window runs longer than 5 seconds.
Why is my CLS 0 in Lighthouse but bad in Search Console?
Lighthouse loads the page once with nobody in front of it, so it only sees the shifts that happen during load. Search Console reports what real visitors got, including shifts from scrolling, clicking and lazy-loaded content. A field CLS is usually worse than a lab CLS.
Which element is causing my layout shift?
Open the layout-shifts audit in the raw Lighthouse JSON. It lists each shifting element with a CSS selector and that element's own contribution to the score. Chrome DevTools shows the same thing in the Performance panel.