All Guides
CLS 7 min read· Updated Apr 2026

How to Fix CLS (Cumulative Layout Shift) — Stop Layout Jank

Eliminate unexpected layout shifts and bring your CLS score below 0.1. Learn the exact causes of layout shift and production-ready fixes for images, fonts, ads, and dynamic content.

What is CLS?

Cumulative Layout Shift (CLS) measures visual stability — how much the page layout shifts unexpectedly while the user is viewing it. A good CLS score is below 0.1. Poor CLS (>0.25) means elements are jumping around, causing accidental clicks and a frustrating experience.


CLS is the most common Core Web Vital failure. Over 50% of sites fail the CLS threshold.

Top Causes of CLS

1.Images without dimensions — the browser doesn't know how much space to reserve
2.Web fonts causing FOUT/FOIT — text reflows when the custom font loads
3.Dynamically injected content — ads, banners, cookie notices pushing content down
4.iframes without dimensions — embeds (YouTube, maps) causing layout shift
5.Late-loading CSS — styles that change layout after initial paint

Fix 1: Always Set Image Dimensions

Always include width and height attributes on images:



html
<img src="/photo.webp" alt="..." width="800" height="450" loading="lazy" />


Or use CSS aspect-ratio:



css
.hero-image {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}


This lets the browser reserve space before the image loads, eliminating shift entirely.

Fix 2: Use font-display: swap

Prevent invisible text (FOIT) and minimize text reflow with font-display:



css
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter.woff2') format('woff2');
  font-display: swap;
  font-weight: 400;
}


Even better, preload your primary font:



html
<link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin />

Fix 3: Reserve Space for Dynamic Content

For ads, banners, or lazy-loaded sections, use CSS min-height to reserve the space:



css
.ad-slot {
  min-height: 250px; /* leaderboard ad */
  background: var(--bg-secondary);
}

.cookie-banner {
  position: fixed; /* doesn't push content */
  bottom: 0;
}


Never insert content above existing content in the DOM.

Test these fixes on your site

Run a free audit to see your current CLS score and get prioritized fix recommendations.

Run Free Audit

Related Guides

LCP8 min

How to Fix LCP (Largest Contentful Paint) — Complete Guide

INP9 min

How to Fix INP (Interaction to Next Paint) — Responsiveness Guide

General5 min

Lazy Loading Images — The Complete Implementation Guide