What is Cumulative Layout Shift (CLS)?
How the impact-and-distance score works, why it now uses session windows, the usual causes of layout jumps, and the one fix behind all of them: reserve space first.
Cumulative Layout Shift (CLS) measures visual stability — how much the content of a page moves around unexpectedly while it loads. It is the metric behind the universally hated experience of reaching to tap a button, having an image or ad load above it, and tapping the wrong thing. CLS is one of the three Core Web Vitals, and a good score is 0.1 or less.
How the score is calculated
CLS is unitless because it is a product of two fractions for each shift. The impact fraction is how much of the viewport the moving elements affected; the distance fraction is how far they moved as a share of the viewport. A large element moving a long way scores badly; a small element nudging slightly barely registers. Since a 2021 change, the reported CLS is not the sum of every shift over the whole visit — it is the worst session window, a burst of shifts grouped in time. That fixed the old unfairness where long-lived pages accumulated a bad score simply by staying open. If you read advice that says CLS sums every shift on the page, it predates this change.
The common causes
Images and video without dimensions. If an <img> has no width and height, the browser does not know how much space to reserve, so everything below jumps down when the image arrives. Ads, embeds, and iframes without reserved space. A slot that collapses to nothing until the ad loads, then expands, shoves the page. Web fonts. When a custom font swaps in for the fallback, text can reflow if the two fonts have different metrics. Content injected above existing content. A cookie banner, a promo bar, or a “you have a new message” strip inserted at the top pushes everything down. Actions that resize after a network response — a component that reserves no space, then grows once its data loads.
How to fix it
The whole fix is one idea: reserve the space before the content arrives. Always set width and height attributes (or a CSS aspect-ratio) on images and video so the browser holds the slot. Give ad and embed containers an explicit minimum size matching what will load. For fonts, use font-display: optional or swap with a metric-matched fallback (the size-adjust descriptor) so the swap does not reflow text, and preload the fonts you need early. Never insert content above existing content unless it is in direct response to a user action. Where something must grow after loading, render a skeleton placeholder at the final size first.
Why it is easy to miss in testing
CLS often looks fine on your own machine and fails in the field, because layout shifts depend on timing that your fast connection hides. On a slow phone the font, the image, and the ad all arrive late and out of order, producing shifts your desktop never shows. This is exactly why field data, not lab data, is what Google scores — and why you should test on a throttled connection, not just trust that the page looked stable when you loaded it.
How to check yours
Our Core Web Vitals checker reports your real-user CLS from field data. The page speed checker runs a Lighthouse lab test that flags the specific elements shifting, which is what you use to find and fix the offending slots — then re-run it to confirm the score dropped before waiting for the field data to follow.
Frequently asked questions
- What is Cumulative Layout Shift (CLS)?
- CLS is a Core Web Vital that measures visual stability — how much a page's content moves around unexpectedly as it loads. It captures the experience of elements jumping just as you go to tap something. CLS is a unitless score, and a good result is 0.1 or less at the 75th percentile of real visitors.
- What is a good CLS score?
- 0.1 or less is good, between 0.1 and 0.25 needs improvement, and above 0.25 is poor. The score is unitless — it comes from how much of the viewport shifted and how far — and is measured at the 75th percentile of your page loads in field data.
- What causes layout shift?
- The most common causes are images and video without width and height set, so the browser reserves no space; ads, embeds, and iframes in containers that collapse then expand; web fonts that reflow text when the custom font swaps in; and content injected above existing content, such as banners. Each one moves the page because space was not reserved ahead of time.
- How do I fix Cumulative Layout Shift?
- Reserve space before content arrives. Set width and height attributes or a CSS aspect-ratio on all images and video, give ad and embed containers an explicit minimum size, use font-display and a metric-matched fallback so font swaps don't reflow text, and never insert content above existing content except in response to a user action. Render skeleton placeholders at the final size for anything that loads late.
- Does CLS count shifts I trigger myself?
- No. CLS only counts unexpected shifts. Movement caused by a user interaction — an accordion expanding, content appearing after a click — is excluded as long as it happens within 500 milliseconds of that interaction. The metric is designed to catch layout jumps the visitor did not ask for, not intentional, interactive changes.
- Why does my CLS pass locally but fail in the field?
- Layout shifts depend on timing that a fast connection hides. On your machine the font, images, and ads arrive quickly and in order; on a real visitor's slower phone they arrive late and out of sequence, causing shifts you never see. That is why Google scores field data from real users, and why you should test on a throttled connection rather than trusting a fast local load.