Skip to content

Cumulative Layout Shift (CLS) Fix

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Cumulative Layout Shift (CLS) Fix. We cover key concepts, practical examples, and best practices.

Your Lighthouse score shows a poor Cumulative Layout Shift (CLS) score above 0.1 — elements on the page shift after rendering because images lack dimensions, dynamic content pushes layout, or web fonts cause invisible text swap.

Step-by-Step Fix

1. Set width and height on images

<!-- Wrong — no dimensions, browser cannot reserve space -->
<img src="hero.jpg" alt="Hero">

<!-- Right — explicit dimensions prevent layout shift -->
<img src="hero.jpg" alt="Hero" width="1200" height="600">

<!-- Or with CSS aspect-ratio -->
<img src="hero.jpg" alt="Hero" style="aspect-ratio: 1200/600; max-width: 100%;">

2. Reserve space for dynamic content

<!-- Wrong — ads/widgets load late and push content down -->
<div class="ad-container"></div>

<!-- Right — reserve space with fixed dimensions -->
<div class="ad-container" style="min-height: 250px; min-width: 300px;">
  <!-- Ad loads here without shifting content -->
</div>

3. Fix web font layout shift

/* Wrong — fallback font has different metrics, causing shift */
body {
  font-family: 'CustomFont', sans-serif;
}

/* Right — use size-adjust to match metrics */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/CustomFont.woff2') format('woff2');
  font-display: swap;
  size-adjust: 95%; /* Match the fallback font metrics */
}

/* Alternative: use font-display: optional to prevent FOIT/FOUT */
body {
  font-family: 'CustomFont', system-ui, sans-serif;
}

4. Use transform for animations

// Wrong — animating layout-triggering properties
element.style.width = "200px";
element.style.top = "50px";
// Causes layout recalculation and shifts

// Right — use transform for the same effect
element.style.transform = "translateY(50px)";
// Only compositing, no layout shift

Common Mistakes

Mistake Fix
Images without width/height attributes Always set explicit dimensions or use aspect-ratio CSS
Inserting content above existing content Reserve space or insert below the fold
Animating top, left, width, height Use transform and opacity for animations
Not reserving space for embeds Set min-height on iframes and embedded widgets
Web fonts with very different metrics Use font-display with size-adjust matching fallback fonts

Prevention

  • Always set width and height on images and videos.
  • Reserve space for late-loading content (ads, embeds, widgets).
  • Use aspect-ratio CSS property for responsive media.
  • Prefer transform and opacity for animations.
  • Test CLS with Chrome DevTools > Performance > Layout Shifts.

DodaTech Tools

Doda Browser highlights layout shifts in its rendering inspector and shows the contributing elements. DodaZIP archives page rendering profiles for CLS regression tracking. Durga Antivirus Pro's UI reserves fixed dimensions for all dynamic content to maintain a CLS score of zero.

Common Mistakes with layout shift

  1. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  2. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
  3. Using return to exit a function early instead of wrapping a pure value in the monad

These mistakes appear frequently in real-world CUMULATIVE code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

What is a good CLS score?

A CLS score of 0.1 or less is considered "good" by Google's Core Web Vitals. A score below 0.25 is "needs improvement", and above 0.25 is "poor". ||| How is CLS measured? CLS measures the sum of all individual layout shift scores that occur during the entire page lifecycle. Each shift is scored by multiplying the impact fraction (how much of the viewport moved) by the distance fraction (how far elements moved). ||| Can CLS be caused by server-side rendering? Yes. If the HTML does not include dimensions for images or space for dynamic content, the browser assigns zero space initially and shifts when content loads — even with SSR.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro