By SitemapFixer Team
Updated October 2026

Cumulative Layout Shift (CLS): What It Is and How to Fix It

Short answer: CLS measures how much visible content jumps around unexpectedly, like a button moving just as you tap it. Good is 0.1 or less for at least 75% of visits; above 0.25 is poor. Almost all layout shift comes from four things: images and videos without set dimensions, ads and embeds without reserved space, content inserted above what’s already on screen, and web fonts that swap in at a different size. Reserve the space before the content arrives, and the shifts go away.

How CLS is scored

Each unexpected shift gets a score: the share of the screen that moved (impact fraction) times how far it moved (distance fraction). If an element filling 75% of the screen moves by 25% of the screen height, that shift scores 0.75 × 0.25 = 0.1875, on its own well over the 0.1 target.

Shifts are grouped into “session windows”: a burst of shifts less than 1 second apart, lasting up to 5 seconds. Your CLS is the worst window, not the sum of the whole visit. Shifts within 500 milliseconds of a tap, click or key press don’t count, because the user expects something to change. Scrolling doesn’t earn that exception.

Find what is shifting

  • PageSpeed Insights: compare field CLS with lab CLS. A big gap means the shifts happen after load (while scrolling), which Lighthouse doesn’t see.
  • Chrome DevTools → Performance: the Layout Shifts track and the “Layout shift culprits” insight show each shift and its likely cause.
  • DevTools live metrics: shows CLS as you scroll and click, so you can catch late shifts yourself.
  • Field data with attribution: the web-vitals library’s attribution build reports which element shifted for real users.

The four causes and their fixes

1. Images and videos without dimensions

The browser doesn’t know how tall an image is until it loads, so it lays out the page without it, then pushes everything down. Give every image and video width and height attributes; CSS keeps it responsive:

<img src="/chart.webp" width="800" height="450" alt="...">

img { max-width: 100%; height: auto; }   /* keeps the 16:9 space reserved */

2. Ads, embeds and iframes

Reserve space with min-height or aspect-ratio, sized for the smallest likely ad or embed. If no ad loads, keep the space (show a placeholder) rather than collapsing it, since collapsing is a shift too.

3. Content inserted above existing content

Cookie banners, “subscribe” bars, and late-loading notices push the page down when injected at the top. Reserve their space in advance, overlay them instead of pushing content, or put them lower on the page. For feeds, load more items on a “Load more” click.

4. Web fonts

When a web font replaces a fallback font of a different size, text reflows. Options from web.dev: font-display: optional (no swap after the first moments), a close fallback with matching metrics via size-adjust, ascent-override, descent-override and line-gap-override, and preloading key fonts:

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

Two more things to check

  • Animations: animate with transform (translate, scale) instead of top, left, width or height, which move other content.
  • Back/forward cache: pages restored from the bfcache start with a CLS of zero, so keeping pages bfcache-eligible helps back and forward navigations.

After fixing, confirm with DevTools while scrolling the page, then watch the field data in Search Console’s Core Web Vitals report over the next few weeks. Background on all three metrics: Core Web Vitals explained.

Frequently asked questions

What is a good CLS score?

0.1 or less for at least 75% of page visits, on mobile and desktop separately. Above 0.25 is poor.

How is CLS calculated?

Each unexpected shift scores impact fraction times distance fraction: how much of the screen moved, times how far it moved. Shifts are grouped into windows (less than 1 second apart, at most 5 seconds long), and CLS is the worst window.

Do layout shifts after a click count?

Not if they happen within 500 milliseconds of a tap, click or key press. Scrolling doesn’t count as such an input.

Why is CLS good in Lighthouse but poor in the field?

Lighthouse only measures the initial load. Real visitors scroll, so ads, lazy-loaded embeds and cookie banners that shift content later only show up in field data.

Do web fonts cause CLS?

They can, when the font swaps in with a different size than the fallback. Use font-display: optional, or match the fallback font’s size with size-adjust and the override descriptors, and preload key fonts.

Related guides