Cumulative Layout Shift
Understand CLS, the Core Web Vital that measures visual stability by quantifying how much the page layout shifts unexpectedly during its lifecycle.
Cumulative Layout Shift (CLS) measures the total amount of unexpected layout movement that occurs throughout the entire lifecycle of a page. A low CLS ensures that the page is visually stable — users won't accidentally click the wrong button because an element suddenly moved.
Thresholds
| Rating | Value |
|---|---|
| Good | ≤ 0.1 |
| Needs Improvement | 0.1 – 0.25 |
| Poor | > 0.25 |
CLS is a unitless score. Unlike the other metrics, it does not measure time — it measures the magnitude and frequency of layout shifts.
How CLS Is Calculated
The browser monitors every unexpected layout shift that occurs without user interaction. Each individual shift produces a layout shift score calculated as:
Layout Shift Score = Impact Fraction × Distance Fraction- Impact Fraction — the percentage of the viewport that was affected by the shift. If a 400px-tall element on a 800px viewport shifts down by 100px, the total impacted area is 500px (the element's original position plus the new area), giving an impact fraction of 500 / 800 = 0.625.
- Distance Fraction — how far the element moved, as a fraction of the viewport's largest dimension. A 100px shift on an 800px viewport gives a distance fraction of 100 / 800 = 0.125.
The final score for that individual shift would be 0.625 × 0.125 = 0.078.
Session Windows
CLS uses a session window approach to group layout shifts. A session window is a burst of shifts where each shift occurs within 1 second of the previous one, with the total window not exceeding 5 seconds. The CLS score is the maximum session window score — the worst burst of shifts, not the sum of all shifts across the page's lifetime.
This approach ensures that pages with long lifespans (like single-page apps) aren't penalized just because they're open longer.
Understanding the Attribution
When attribution is enabled, FastStats provides detail about the largest layout shift in the session window:
- Largest Shift Target — the CSS selector of the DOM element that shifted the most
- Largest Shift Time — when the shift occurred (ms from navigation start)
- Largest Shift Value — the individual score of the largest single shift
- Load State — the document's loading state when the shift happened (
loading,dom-interactive,dom-content-loaded, orcomplete)
This lets you pinpoint the exact element causing instability and when it happened.
Common Causes of Poor CLS
Images and Videos Without Dimensions
When images load without explicit width and height attributes, the browser allocates zero space initially. Once the image loads, surrounding content is pushed out of the way.
Fix: Always set width and height attributes on <img> and <video> elements, or use the CSS aspect-ratio property:
<img src="/photo.webp" width="800" height="600" alt="Description" />img {
aspect-ratio: 4 / 3;
width: 100%;
height: auto;
}Dynamically Injected Content
Banners, cookie consent bars, ads, or notification bars that get inserted above existing content push everything down.
Fix: Reserve space for dynamic content with CSS min-height or by placing injected elements in a dedicated container that doesn't affect the layout of surrounding content. Prefer overlays or fixed-position elements for banners.
Web Fonts Causing FOUT/FOIT
When a web font loads and replaces a fallback font, text reflows because the metrics (line height, letter spacing, etc.) differ between fonts.
Fix:
- Use
font-display: optionalto avoid layout shifts entirely (falls back gracefully if the font isn't cached) - Use
font-display: swapwith a size-adjusted fallback font viasize-adjust,ascent-override, anddescent-overrideCSS descriptors - Preload critical fonts:
<link rel="preload" as="font" href="/font.woff2" crossorigin />
Late-Loading CSS or JavaScript
Stylesheets or scripts that load after initial render can apply new styles that reposition elements.
Fix: Inline critical CSS, load non-critical CSS asynchronously, and avoid JavaScript that modifies layout after the initial render.
Animations That Trigger Layout
Animations that change top, left, width, height, or other layout-triggering properties cause layout shifts.
Fix: Use transform for animations instead of layout properties. transform: translateX() and transform: scale() are composited by the GPU and don't trigger layout.
Layout shifts that occur within 500ms of a user interaction (like a click or keypress) are excluded from CLS. These are considered expected layout changes.
Interpreting CLS in FastStats
The metric detail page shows:
- p75 timeline — your CLS score over time
- Distribution chart — how your CLS values spread across good, needs improvement, and poor
- Breakdown by page — which routes suffer from the most layout instability
- Shift targets — the specific DOM elements causing the largest shifts (when attribution is enabled)
- Load state correlation — whether shifts happen during loading or after the page is fully loaded
Web Vitals
Monitor real-world user experience with Core Web Vitals and performance metrics. Track LCP, CLS, INP, FCP, and TTFB across your website.
First Contentful Paint
Understand FCP, the performance metric that measures how quickly the first piece of content renders on screen after navigation begins.