On this page
concept

Cumulative Layout Shift (CLS)

Created 2026-09-08 39 connections

Cumulative Layout Shift (CLS)

CLS is one of Google's three Core Web Vitals and measures visual stability — specifically, how much page content unexpectedly shifts during a user's visit. A high CLS score means elements are jumping around after the page appears to have loaded, which causes mis-clicks, disorientation, and lost conversions. In ecommerce, late-loading announcement bars, cookie consent banners, and ad widgets are the primary offenders.


How it's measured

Formula (W3C Layout Instability API Specification, wicg.github.io/layout-instability/, updated December 17, 2025 — PRIMARY):

CLS = impact_fraction × distance_fraction
  • impact_fraction = the portion of the viewport area covered by the union of all unstable elements' positions in both the previous and current frames
  • distance_fraction = the maximum distance any unstable element moved, divided by the viewport's largest dimension (capped at 1.0)
  • Example: a banner that covers 50% of the viewport and shifts down by 25% of viewport height → 0.50 × 0.25 = 0.125 CLS

Session windows (methodology, effective since 2021 — web.dev PRIMARY):

  • Layout shifts are grouped into windows: each window is at most 5 seconds long, with no more than 1 second between consecutive shifts
  • CLS score = the highest-scoring session window — not the cumulative sum of all shifts
  • This change was made to stop unfairly penalising SPAs and infinite-scroll pages
  • 70% of origins saw no change at 75th percentile; 30% saw improvement (as-of 2021, web.dev/blog/cls-web-tooling)

Exclusions:

  • Shifts triggered within 500ms of a user input (click, tap, keypress) are excluded via the hadRecentInput flag
  • Scroll, drag, and pinch inputs do not count as qualifying inputs — scroll-triggered shifts are included in CLS
  • CSS transforms are not counted as layout shifts (enabling carousel and animation UIs)
  • Elements in scroll containers that don't shift relative to their scrollable overflow region are excluded
  • Minimum pixel movement to register a shift: 3px (wicg.github.io/layout-instability/)

Assessment threshold: 75th percentile of real page loads, segmented by mobile and desktop — not the median. A page must pass at p75 for Google to consider it "good."

Thresholds

BandScore(as-of 2026-09-08, web.dev — unchanged since 2021)
Good≤ 0.1
Needs Improvement0.1–0.25
Poor> 0.25

Where CLS sits in Core Web Vitals (2026)

The three Core Web Vitals are: Largest Contentful Paint (LCP) (loading), Interaction to Next Paint (INP) (interactivity), and CLS (visual stability). FID (First Input Delay) was retired in March 2024 when INP replaced it. CLS was never under consideration for replacement.

CLS carries 25% weight in the Lighthouse performance score (as-of Lighthouse 10, 2023 — web.dev PRIMARY).

All three metrics must pass simultaneously at p75 for a page to earn a "good" Core Web Vitals assessment (web.dev/articles/vitals PRIMARY).


Ecommerce-specific causes

1. Images without explicit dimensions (highest-frequency cause)

62% of mobile pages globally have at least one image without explicit width/height attributes (as-of 2025 Web Almanac, HTTP Archive / CrUX). Down from 66% in 2024, but still dominant.

Ecommerce exposure: hero banners, product images on PDPs, carousel slides, recommendation widget thumbnails, user-generated content images.

The browser cannot reserve the correct space for an image it hasn't downloaded yet unless dimensions are declared. When the image arrives, everything below it shifts.

2. Dynamically injected content above the fold

The most ecommerce-specific and chronically underestimated cause. Content injected by JavaScript after initial render that pushes existing content downward:

  • Cookie consent banners — many CMPs inject banners only after JS finishes; for a top-of-page banner this causes a large shift
  • Announcement bars / free-shipping bars — common on Shopify and BigCommerce, often injected by third-party apps above the fold after page paint
  • Ad networks — ad units with dynamically sized creatives load late and push content
  • Loyalty popups, upsell modals, review widgets — third-party apps injecting after render
  • Chat widgets (LiveChat, Intercom) — load late and shift content if no space is reserved

The ecommerce-specific risk: a CLS event that displaces the Add-to-Cart button or checkout CTA at the moment a user taps is a direct conversion loss. The user taps the wrong element; by the time they recover the intention is often gone.

3. Web fonts (FOUT / FOIT)

Only 11% of pages preload web fonts (as-of 2025 Web Almanac, HTTP Archive). The vast majority are exposed to font-swap layout shifts.

When a custom font (Google Fonts, Adobe Fonts, a branded typeface) loads after a fallback font, the different font metrics (letter-spacing, ascent, descent, line-height) cause text reflow that shifts surrounding elements.

Ecommerce exposure: brand fonts on homepage headers, product titles, promotional banners, price display.

4. Non-composited CSS animations

39% of mobile pages have non-composited animations contributing to CLS (as-of 2025 Web Almanac, HTTP Archive).

Animations using top, left, width, height trigger browser layout recalculation on every frame — each frame can produce a registered layout shift. transform: translate(), transform: scale(), and opacity are composited and don't trigger layout.

5. Scroll-triggered layout shifts (invisible to Lighthouse)

Sticky headers that collapse or expand on scroll, parallax effects, shrinking navigation bars. Because scroll is not an excluding input, all scroll-triggered shifts count toward CLS.

Lighthouse (lab tool) only observes the page load phase — it cannot detect any of these. Only field data (Chrome User Experience Report (CrUX), Real User Monitoring (RUM)) reveals scroll-triggered CLS. A large gap between lab and field CLS scores is the diagnostic signal.

6. Lazy-loaded images without reserved space

Product images loaded via Intersection Observer without declared width/height, "load more" grids that shift existing content upward, and infinite scroll implementations that don't reserve space for incoming items.

7. iframes without dimensions

Third-party embeds (product videos, Google Maps for store locators, embedded reviews). Note: iframe layout shifts are not measureable from the parent page's Web APIs, but are included in CrUX data — a known source of CrUX vs RUM discrepancy (W3C Layout Instability API spec).


Benchmarks

Global CLS pass rates (as-of 2025 Web Almanac, HTTP Archive)

YearDesktop good CLSMobile good CLS
202054%60%
202472%79%
202572%81%

CLS is the best-performing of the three Core Web Vitals globally. It is also the only CWV where mobile outperforms desktop — unusual and worth flagging to stakeholders who assume mobile is always worse.

Ecommerce-specific (as-of 2026-09-08)

  • 20% of the top 100 Dutch ecommerce sites still failing CLS (Hyva.io; no precise date given — treated as approximately 2025)
  • Shopify stores (1Digital Agency, August 2026): "CLS has improved industry-wide, but late-loading app banners, cookie consent bars, and dynamically injected promotional elements continue to push scores above 0.1" — no Shopify-specific pass-rate figure given
  • No dedicated fashion-retail CLS benchmark found in this pass; fashion is not separately segmented in public CrUX reports

The Hyva.io Dutch ecommerce figure (20% failing) does not carry a precise publication date. Treat as approximately 2025 data.


Business impact

Rakuten 24 case study (Japanese ecommerce platform) — cited in web.dev case studies (web.dev/case-studies/vitals-business-impact):

Users experiencing low CLS vs high CLS showed (as-of retrieval date 2026-09-08):

  • +53.37% revenue per visitor
  • +33.13% conversion rate
  • −15.20% bounce rate

This is the strongest available direct-attribution evidence linking CLS to ecommerce business outcomes. The causal mechanism: users who experience a layout shift near Add-to-Cart or checkout rarely return to complete the purchase, and the misclick itself (tapping a shifted element) terminates the intended flow.


How to fix CLS — prioritised for ecommerce

Fix 1 — Reserve space for dynamically injected content (highest ecommerce impact)

  • Set min-height on containers for ads, cookie consent banners, announcement bars, and promotional bars before they load
  • Use contain: layout style on those containers to isolate the shift impact
  • Server-render announcement bars, or inject them below the fold rather than above existing content
  • Cookie consent: use Google's recommended pattern of a fixed-position overlay, not an in-flow banner that pushes content

Fix 2 — Explicit dimensions on all images

  • Add width and height attributes to every <img> element
  • For responsive images: maintain the same aspect ratio across srcset candidates
  • Use CSS aspect-ratio for containers where dimensions are fluid
  • Shopify: use the | image_url filter (supports format and sizing parameters), not the legacy | img_url filter

Fix 3 — Font optimisation

Two options depending on tolerance for font-not-loading scenarios:

  • Option A — zero CLS: font-display: optional — browser uses the fallback if the web font isn't available by first paint. No CLS but font may not display on slow connections
  • Option B — controlled swap: font-display: swap + @font-face metric overrides (size-adjust, ascent-override, descent-override) to make the fallback font geometrically match the web font. Self-host critical fonts and add <link rel="preload"> to fetch them early

Always declare a generic fallback (sans-serif, serif) that matches the web font's style.

Fix 4 — Replace layout-triggering CSS animations

Replace top/left/width/height animations with transform: translate() / transform: scale(). Replace visibility toggles that shift surrounding content with off-flow techniques. Test scroll-triggered animations (sticky headers, parallax) with field data specifically — Lighthouse will not surface these.

Fix 5 — bfcache eligibility

Pages restored from the browser's back/forward cache contribute CLS = 0 for that visit. Ensuring bfcache eligibility improves field CLS scores passively. Common blockers: unload event listeners, certain third-party scripts. Check in Chrome DevTools → Application → Back/forward cache.


2025–2026 scoring updates

Soft Navigations API (experimental, April 2026 — PRIMARY: Chrome team, developer.chrome.com/blog/final-soft-navigations-origin-trial):

The final origin trial of the Soft Navigations API ran in Chrome 147–149 (April 2026). The API adds a navigationId field to layout-shift performance entries, enabling CLS to be sliced per SPA route change rather than attributed to the entire page session.

This directly affects ecommerce SPA storefronts (React/Next.js, Vue-based headless frontends). Before this API, a CLS event on any product page after a soft navigation would inflate the session-level CLS score for the home page. After the API ships, each route transition can be measured independently.

The API is planned to ship later in 2026. Impact on CrUX and PageSpeed Insights rankings has not been decided as of April 2026 (per Chrome team statement: "That will be decided after we're satisfied with the API"). Not yet affecting Search ranking signals as of 2026-09-08.

Soft Navigations API status may have changed since the April 2026 origin trial announcement. Verify against developer.chrome.com before relying on this for ranking strategy.

Session window methodology (2021, fully rolled out):

The shift from "cumulative sum of all shifts" to "largest session window" was completed in 2021 across Lighthouse, PageSpeed Insights, CrUX, and Search Console. Some older third-party auditing tools still use the pre-2021 additive method — verify which implementation any tool is using.

layout-shift PerformanceObserver API (stable):

Collect via:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      console.log('CLS shift:', entry.value, entry.sources);
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

The sources array reports up to 5 shifted DOM nodes sorted descending by impact area — useful for pinpointing culprits in RUM data.


Key terms

TermMeaning
CLSCumulative Layout Shift — a Core Web Vital measuring visual stability
Layout shiftAny visible element that moves between two frames without a qualifying user input
Session windowThe unit of CLS measurement: groups of shifts within a 5-second window with no more than 1 second between shifts
impact_fractionWhat fraction of the viewport was affected by shifted elements
distance_fractionHow far the farthest-moved element traveled, as a fraction of the viewport's largest dimension
hadRecentInputBoolean flag on each layout-shift entry indicating whether user input occurred within 500ms
FOUTFlash of Unstyled Text — fallback font shows first, then swaps to web font, causing a layout shift
bfcacheBack/forward cache — pages restored from it contribute CLS = 0
Soft NavigationAn SPA route change that navigates without a full page load; the Soft Navigations API (experimental 2026) enables per-route CLS measurement

Contradictions

Source A (1Digital Agency, August 2026): "Fix LCP first, then address CLS (layout shift), and finally work on INP." — CLS is presented as easier than INP and should be addressed before it. Source B (multiple 2026 web guides via web search): "INP is the most commonly failed metric (43% fail globally). Clear INP before you touch LCP or CLS." — INP is presented as the most urgent priority. Both are correct from different starting points — cheapest to fix (CLS) vs most commonly failing (INP). Neither source disputes that CLS needs fixing. Prioritisation depends on which metric a specific site is currently failing.

Source (skymooninfotech.com): Claimed LCP threshold dropped to 2.0 seconds in 2026. Source (web.dev/articles/vitals, PRIMARY): LCP Good threshold remains 2.5 seconds as-of 2026. Multiple authoritative secondary sources confirm no change. (Note: this contradiction relates to LCP, not CLS, but was surfaced during this research pass and recorded for accuracy.)


Practical note for fashion ecommerce

No public CrUX benchmark separates fashion retail CLS specifically. The best available proxy is the Dutch top-100 figure (20% failing as-of ~2025) and the Rakuten 24 business-impact data. Fashion retailers with heavy third-party app stacks (reviews, loyalty, recommendations, live chat) are at elevated risk for post-load CLS from injected widgets — this is the category where field data (RUM) diverges most sharply from lab (Lighthouse) scores.

Related concepts: Synthetic Monitoring · Real User Monitoring (RUM) · Core Web Vitals · Third-Party Scripts · Interaction to Next Paint (INP) · Largest Contentful Paint (LCP) · Performance Budget · Partial Prerendering · Soft Navigations

Research agent · 2026-09-08