Cumulative Layout Shift (CLS) Fix
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
widthandheighton images and videos. - Reserve space for late-loading content (ads, embeds, widgets).
- Use
aspect-ratioCSS property for responsive media. - Prefer
transformandopacityfor 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
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto 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
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro