Cumulative Layout Shift (CLS): Definition, Causes, Fixes

CLS is a Core Web Vital measuring unexpected visual shifts during page load. ≤ 0.1 = good. Caused by missing image dimensions, dynamic ads, late fonts.

What is Cumulative Layout Shift (CLS)?

Cumulative Layout Shift (CLS) is a Core Web Vital that measures the total amount of unexpected visual shifting that happens during a page's lifetime. Every time content jumps because an image loads late, an ad injects, or a font swaps, that's a layout shift — and it's frustrating for users (clicked the wrong button, lost their place in the article).

CLS is one of three Core Web Vitals (with LCP and INP) that Google uses as a search ranking signal. Pages with high CLS rank lower and feel broken, even if they technically work.

How CLS is measured

CLS = sum of layout shift scores during page lifetime. Each shift score = impact fraction × distance fraction:

  • Impact fraction: how much of the viewport was affected by the shift
  • Distance fraction: how far elements moved (relative to viewport)
CLSRating
≤ 0.1Good
0.1 - 0.25Needs Improvement
> 0.25Poor

Reported as the worst "session window" — a 5-second window of consecutive shifts.

What causes CLS

CauseWhyFix
Images without width/heightBrowser doesn't know how much space to reserveAlways set width + height attrs
Ads, embeds, iframesInject content of unknown size after page rendersReserve space with explicit dimensions or skeleton
Web fonts loading lateFOUT/FOIT swaps fallback for web font, sizes differfont-display: optional or size-adjust
Dynamic content above existingContent injected at top pushes everything downAppend below, not above; or reserve space
Animations that change layoutAnimating height/width moves siblingsUse transform (doesn't affect layout)
Cookie/GDPR banners appearingTop banner pushes content downPosition fixed, or reserve space

Common CLS fixes

1. Always specify image dimensions

<!-- BAD: causes CLS -->
<img src="hero.jpg" alt="Hero">

<!-- GOOD: aspect ratio reserved -->
<img src="hero.jpg" alt="Hero" width="1200" height="675">

<!-- For responsive images, browser computes aspect ratio -->

2. Reserve space for ads/embeds

<!-- Ad slot with reserved height -->
<div class="ad-slot" style="min-height: 250px;">
  <!-- Ad fills it -->
</div>

3. Optimize web fonts

@font-face {
  font-family: 'Inter';
  src: url('inter.woff2') format('woff2');
  font-display: optional; /* No swap */
  size-adjust: 95%; /* Match fallback metrics */
}

4. Use transform, not layout properties

/* BAD: animating height triggers reflow */
.menu { transition: height 0.3s; }

/* GOOD: transform doesn't affect layout */
.menu { transition: transform 0.3s; transform: translateY(0); }

5. Avoid late-injected top content

<!-- Don't insert above existing content -->
<div id="banner"></div>  <!-- empty placeholder -->
<main>...</main>

// JS: only fill banner; don't push main down
document.getElementById('banner').textContent = 'Welcome!';

Measuring CLS

ToolType
Lighthouse / PageSpeed InsightsLab + field
Chrome DevTools Performance PanelLab, frame-by-frame
Web Vitals Chrome extensionField, real browsing
web-vitals.js libraryProgrammatic, RUM
Google Search Console CWV reportField, your real users
CrUX DashboardField, public dataset
// Capture CLS in JS
import { onCLS } from 'web-vitals';
onCLS((metric) => {
  console.log('CLS:', metric.value);
  // Send to RUM backend
});

CLS best practices

  • Always set width/height on images and videos. Browser computes aspect ratio.
  • Reserve space for everything that loads late. Ads, embeds, iframes, lazy-loaded content.
  • Use font-display: optional for non-critical fonts. Avoids FOUT.
  • Match fallback font metrics with size-adjust. Reduces font swap shift.
  • Transform animations, not layout. transform + opacity are GPU-cheap and CLS-free.
  • Skeleton screens. Show placeholder of same dimensions as final content.
  • Don't inject above existing content. Append, don't prepend.
  • Test on slow devices. CLS is worse with slow loading; test on throttled mobile.

Common CLS pitfalls

  • Responsive image without aspect ratio. Browser doesn't know height until loaded.
  • Web fonts that resize text. Fallback Arial vs custom font with different metrics.
  • Lazy-loaded ads with no reserved space. Ad pops in mid-scroll, jumps content.
  • Click handlers on shifting elements. User clicks "Subscribe", button shifts, "Buy" takes the click.
  • Auto-rotating carousels. Each rotation can shift adjacent content.
  • Late-loading hero image. Container collapses then expands when image arrives.

FAQ: Cumulative Layout Shift

What's a good CLS score?

≤ 0.1 is good. 0.1-0.25 needs improvement. > 0.25 is poor.

Does CLS affect SEO?

Yes — it's one of three Core Web Vitals Google uses as a ranking signal. High CLS = lower ranking on competitive queries.

How do I fix images causing CLS?

Always set width and height attributes (or use aspect-ratio CSS). Browser reserves the right amount of space before image loads.

Do scrolling and user interactions count toward CLS?

No. Shifts within 500ms of user input are excluded. Only unexpected shifts count.

How does font-display affect CLS?

font-display: swap shows fallback then swaps — causes shift. optional shows fallback only if web font isn't ready quickly. Use optional + size-adjust for best CLS.

Can I have CLS = 0?

Possible but rare. Most sites with ads or dynamic content have some shift. Aim for < 0.1.

What is "session window" in CLS?

5-second window of consecutive shifts. CLS reports the largest such window's total shift, not all shifts summed across the entire page lifetime.

Catch CLS regressions with LoadFocus

LoadFocus runs Lighthouse audits from 25+ regions and tracks CLS over time, alerting on regressions before they hurt SEO. Sign up free at loadfocus.com/signup.

How fast is your website?

Elevate its speed and SEO seamlessly with our Free Speed Test.

Free Website Speed Test

Analyze your website's load speed and improve its performance with our free page speed checker.

×