Cumulative Layout Shift (CLS) is a Core Web Vital that measures the total amount of unexpected movementof visible page elements during a user's session. It's the metric behind every "the button moved right as I tried to click it" experience — and Google uses it as a direct ranking signal.
Think of CLS the way you think of pulling out a chair just as someone sits down. Even one shift is enough to break trust — and on the web, the cost is misclicks on the wrong button, accidental purchases, and visitors who never come back.
CLS is one of the few metrics where the user pain is immediately visible. It directly affects:
CLS is the sum of layout shift scores for every unexpected movement that occurs during a session window. Each individual shift score is calculated as:
Layout Shift Score = Impact Fraction × Distance Fraction
In that example: 0.4 × 0.25 = 0.1— already at Google's "good" ceiling from a single shift.
Since the 2021 CLS update, Google measures the worst 5-second windowof consecutive shifts (with no more than 1-second gaps), not the lifetime sum. This means very long pages no longer accumulate "unfair" CLS — only the worst burst counts.
Layout shifts that occur within 500 ms of a user interaction(a click, tap, or keypress) are flagged as "expected" and excluded from CLS. So a "Read more" button that expands content does not hurt your score. Only shifts that happen on their own — usually during loading — are counted.
CLS, like the other Core Web Vitals, is measured both in the lab (synthetic) and in the field (real user data via the Chrome User Experience Report). Google weights field data for ranking purposes.
The single most common cause of bad CLS is images without dimensions. Without explicit width/height, the browser reserves zero space — then jumps when the image arrives.
Fix: Add width and height attributes to every <img> and <video>. Modern browsers use these to compute an aspect ratio and reserve the correct space before the file loads.
For responsive media (images that scale with the viewport), the aspect-ratio CSS property reserves space proportionally — preventing shifts on every screen size.
img, video {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}Ad slots, social embeds, and chat widgets are repeat CLS offenders because they inject content asynchronously.
Fix: Wrap every ad slot in a fixed-size container that matches the largest expected ad. If the slot fills, no shift. If it stays empty, you keep a tiny bit of whitespace — a far better trade than a full-page jump.
When a custom font swaps in after the system fallback has already painted, line lengths change and surrounding text reflows.
Fix: Preload critical fonts with <link rel="preload" as="font">, use font-display: optional when feasible, and set size-adjust, ascent-override, and descent-override on the fallback so it occupies the same vertical space as the final font.
Animating top, left, width, or margin triggers full layout recalculation and can cascade shifts to siblings.
Fix: Use transform: translate() and opacity for animations. They run on the compositor thread and never trigger layout.
Cookie banners, promo bars, and notifications inserted at the top of the page push everything else down — typically a large impact fraction × large distance fraction = a very high shift score.
Fix: Either render these elements server-side so they're present at first paint, or position them with position: fixed so they overlay rather than displace content.
When data-driven sections (related posts, comments, product recommendations) appear after the initial render, they push surrounding content unless you reserve space.
Fix: Render skeleton placeholders with the same dimensions as the final content. When real content arrives, the swap is in-place.
min-height: auto on Carousels and TabsWhen a carousel or tabs widget reflows to its content height on each slide change, the surrounding page can shift unexpectedly.
Fix: Set a fixed min-height based on the tallest expected slide so the container size stays constant across states.
Footers and CTAs that re-position when new content loads at the bottom of an infinite-scroll feed can register as shifts in the user's active session window.
Fix: Pre-load the next batch before the user reaches the end, and remove or fix-position any element that would otherwise be displaced.
What's happening: Images load without reserved space, pushing every element below them downward as they arrive.
Fix: Add width and height attributes (or aspect-ratio CSS) to every image. This is the single highest-impact CLS fix on most sites.
What's happening: The banner is inserted at the top of the body after first paint, displacing everything below it.
Fix: Use position: fixed at the bottom or top of the viewport so the banner overlays content instead of moving it. Alternatively, render it server-side so it's present at first paint.
What's happening: Social embeds, review widgets, and chat icons inject themselves asynchronously into containers with no reserved size.
Fix: Wrap each widget in a fixed-size container. If the widget fails to load, the container holds the space — preventing a delayed shift.
What's happening: The fallback system font and the loaded custom font have different metrics, causing line breaks to change when the swap happens.
Fix: Use size-adjust, ascent-override, and descent-override on a @font-face fallback declaration to match the custom font's vertical metrics.
CLS is the only Core Web Vital that doesn't measure speed. It can be excellent on a slow site or terrible on a fast one — they measure entirely different aspects of the experience.
| Metric | What It Measures | Good Threshold | Difference From CLS |
|---|---|---|---|
| Largest Contentful Paint (LCP) | When the largest visible element finishes loading | ≤ 2.5 s | LCP is about speed; CLS is about stability. |
| Interaction to Next Paint (INP) | Responsiveness to clicks, taps, and keypresses | ≤ 200 ms | INP measures input delay; CLS measures unprompted visual movement. |
| First Contentful Paint (FCP) | When any visible content first appears | ≤ 1.8 s | FCP marks the start of the render; CLS measures what happens during and after. |
| Total Blocking Time (TBT) | How long the main thread is blocked during load | ≤ 200 ms | TBT is about JavaScript responsiveness; CLS is about visual movement. |
Google defines a good CLS as 0.1 or less. Scores between 0.1 and 0.25 "need improvement," and anything above 0.25 is considered poor. The threshold applies to the 75th percentile of real-user sessions — meaning 75% of visits must come in under 0.1 to pass.
Yes. CLS is one of the three Core Web Vitals that became a confirmed ranking signal in June 2021 via the Page Experience update. Google uses field data from the Chrome User Experience Report (CrUX), not synthetic lab scores, for the ranking signal.
Originally, CLS summed every layout shift across the entire page lifetime, which unfairly penalized long-lived single-page apps. The 2021 update introduced session windows: the score is now the maximum 5-second window of consecutive shifts (with no more than 1-second gaps). The headline number you optimize against is that worst burst.
No — shifts that occur within 500 ms of a user input (click, tap, keypress) are excluded. So an accordion expanding when someone clicks "Read more" does not affect your score. Only shifts that happen without user prompting are counted.
Because images without explicit width and height attributes default to taking zero space until they finish downloading. Once the image arrives, the browser inserts its full dimensions, pushing every element below it down — usually with a large impact fraction and a meaningful distance fraction, which multiply into a high shift score.
Indirectly. Generative search systems most often surface pages that are already ranking well in traditional search — and CLS is part of that ranking signal. Additionally, Google AI Overviews preferentially cites pages that pass Core Web Vitals. A failing CLS reduces both your search visibility and your odds of being chosen as a citation.
Yes — but it requires deliberate effort. Reserve space for every async section with skeletons, animate route transitions with transform rather than layout properties, and ensure modals and toasts use position: fixedoverlays. The 5-second session window means a single bad transition can dominate your score, so it's worth profiling each route change.
CLS is the Core Web Vital users feel most viscerally — the missed click, the lost reading position, the cookie banner that pushed your headline off the screen. It's also one of the easiest to fix: reserving image dimensions, wrapping ads in sized containers, and preloading fonts will get most sites under the 0.1 threshold without architectural changes.
The business case is clear — Yahoo! JAPAN News drove a 15% increase in page views by getting CLS under 0.1. Run a Greadme deep scan to identify exactly which elements are shifting on each page, then fix them in order of impact.