Skip to main content

Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS) measures visual stability by tracking how often and how far elements move unexpectedly during load. CLS problems feel like "the page is jumping" and often lead to misclicks (especially on mobile), which is why it's both a UX issue and a Core Web Vitals issue.

Quick Summary

CLS heavily penalizes pages where an asset loads late and forces existing content downwards. Eliminating this requires hardcoding width and height dimensions on all media, preventing Flash of Unstyled Text (FOUT), and strictly controlling how advertising containers render above the fold.

Common CLS Triggers

Trigger PointTypical ExampleStructural Fix
Images lacking dimensions<img src="hero.jpg"> without HTML width/height attributesHardcode width + height alongside explicit CSS aspect-ratio commands
Ads / iframes / embedsGoogle AdSense banners pushing content down lateReserve physical space instantly using an empty CSS container with a fixed min-height
Web Fonts (FOIT/FOUT)A flash of invisible or un-styled text morphing dimensionsPreload fundamental fonts and explicitly enforce font-display: swap
Dynamic DOM InjectionCookie banners or promos appearing above the headerPre-allocate the header gap or trigger these exclusively as overlapping modals
Lazy Loading above-the-foldThe main hero image snapping into view violentlyNever lazy load anything located in the initial visual viewport; utilize loading="eager"

Step-by-Step Examples

Identify Shifting Elements in DevTools

  1. Open Chrome DevTools and navigate to the Rendering tab.
  2. Check the box for Layout Shift Regions.
  3. Reload the page, ideally under a slow network throttle.
  4. Watch the viewport: Shifting elements will flash bright purple.

Force Dimensions on Responsive Media

image-dimensions.html
<!-- Failure: The browser cannot reserve space until the file downloads -->
<img src="product.jpg" alt="Product Description">

<!-- Success: The browser secures the necessary area in the DOM instantly -->
<img src="product.jpg" alt="Product Description" width="800" height="600" style="aspect-ratio: 4/3;">

Reserve Space for Advertising Networks

ad-container-reservation.css
/* Reserve exact vertical real estate for dynamic AdSense integration */
.ad-container-hero {
min-height: 250px;
width: 100%;
display: block;
background-color: #f8f9fa; /* Prevents jarring visual pop-in */
}

Preload Typography to Eradicate FOUT

font-preload-header.html
<!-- Accelerate discovery inside the <head> -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter.woff2" crossorigin>
font-css-rules.css
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap; /* Forcibly displays fallback text to prevent invisible layouts */
}

Practical Scenarios

WooCommerce Product Pages

Problem: The main catalog image loads without pre-allocated dimensions; when it renders, it pushes the "Add to Cart" button downward precisely as the user taps their screen. Fix: Inject strict global width/height variables onto all WooCommerce product media hooks and enforce aspect-ratio across the gallery CSS.

Heavily Monetized Blogs

Problem: Late-firing asynchronous JavaScript injects massive AdSense banners into the middle of paragraphs, destroying the reading flow with a 0.35 CLS. Fix: Wrap the AdSense anchor div tags in strictly sized CSS containers (min-height) that artificially hold the space open while the ad executes.

Problem: Shrinking a sticky navigation bar upon scrolling radically alters its physical height, shoving all <body> content down repeatedly. Fix: Always decouple animation mechanics from structural footprint. Animate via CSS transform: translateY() instead of physically reducing height or padding.

Common Mistakes & Troubleshooting

MistakeExplanationSolution
Fixing CLS only on desktopA layout that is stable on desktop can still shift on mobile due to different breakpoints and font sizes.Validate on mobile (real devices or emulation) and confirm with field data.
Depending on Lab DataThird-party chat widgets or ads frequently behave entirely differently in PageSpeed Insights compared to the wild.Rely primarily on field metrics aggregated in Google Search Console.
Trusting height: auto aloneAuto-height provides no reserved space before the media asset arrives.Combine responsive media with explicit dimensions or aspect-ratio.
Injecting banners earlyJamming a promotional notification above the <nav> late in the load sequence.Trigger overlay notifications (position: fixed) that sit cleanly above the DOM structure.

Quick Reference

CLS Target Cheat Sheet

Thresholds:

RatingCLS
Good≤ 0.1
Needs Improvement0.1 – 0.25
Poor> 0.25

Immediate Validation:

  1. Hardcode HTML width/height into every primary image.
  2. Secure empty container blocks for asynchronous ad delivery.
  3. Preload the primary stylesheet font directly.
  4. Exclude all above-the-fold media from lazy-load interference.

Visual CLS Render Flow

What's Next