DEV Community

Zahid Awais
Zahid Awais

Posted on Fully Autonomous

How to Find and Fix Layout Shift (CLS) Using Chrome DevTools: A Practical Guide

Have you ever started reading a page, and the text suddenly jumped down because an image or ad loaded above it? That jump is a layout shift, and Google measures it with a Core Web Vital called Cumulative Layout Shift (CLS).

A good CLS score is 0.1 or less. Anything above 0.25 is considered poor, and it can hurt both user experience and your rankings.

In this guide I will show you how I find the exact elements causing layout shift with Chrome DevTools, and the fixes that solve most CLS problems in a few minutes.

What actually causes layout shift?

In my SEO audits, almost every CLS problem comes from one of these five things:

  1. Images and videos without width and height: the browser does not know how much space to reserve.
  2. Ads, embeds and iframes that load late and push content down.
  3. Web fonts that swap and change the size of text (FOUT/FOIT).
  4. Content injected with JavaScript above existing content (cookie bars, banners, "related posts" widgets).
  5. Animations that change top, left, width or height instead of transform.

Step 1: Measure CLS before you change anything

Run the page through PageSpeed Insights or Lighthouse in DevTools (F12 → Lighthouse → Analyze page load). Note two numbers:

  • Field data (real users): what Google actually uses for ranking.
  • Lab data: useful for testing your fixes quickly.

If you want a quick overall health check of the page (CLS plus titles, headings, meta tags and other on-page issues), you can also run it through this free SEO audit tool.

Step 2: Find the shifting elements in DevTools

  1. Open DevTools and press Ctrl + Shift + P (Cmd + Shift + P on Mac).
  2. Type Rendering and open the Rendering panel.
  3. Enable Layout Shift Regions.
  4. Reload the page.

Every element that moves will flash blue. Now you can see exactly what is jumping instead of guessing.

For more detail, open the Performance panel, record a page load, and look at the Layout Shifts track. Click on any shift and DevTools will show you the moved nodes.

Step 3: Log layout shifts with a small script

Sometimes shifts happen after scrolling or clicking, and they are hard to catch visually. Paste this into the Console:

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.hadRecentInput) continue;
    console.log('Layout shift:', entry.value.toFixed(4));
    entry.sources?.forEach((s) => console.log('  moved:', s.node));
  }
}).observe({ type: 'layout-shift', buffered: true });
Enter fullscreen mode Exit fullscreen mode

Every shift is logged with its score and the DOM node that moved. Hover over the node in the console and it will be highlighted on the page.

Step 4: Apply the fixes

Fix 1: Always set image dimensions

<img src="hero.webp" width="1200" height="630" alt="Hero image">
Enter fullscreen mode Exit fullscreen mode

Modern browsers use these attributes to calculate the aspect ratio before the image loads. Keep it responsive with CSS:

img { max-width: 100%; height: auto; }
Enter fullscreen mode Exit fullscreen mode

Fix 2: Reserve space for ads and embeds

.ad-slot { min-height: 250px; }
.video-embed { aspect-ratio: 16 / 9; width: 100%; }
Enter fullscreen mode Exit fullscreen mode

Fix 3: Load fonts without big jumps

<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
Enter fullscreen mode Exit fullscreen mode
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap;
  size-adjust: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Choosing a fallback font with similar metrics (or using size-adjust) keeps the swap almost invisible.

Fix 4: Never insert content above existing content

Cookie banners and notification bars should be overlays (position: fixed) or have their space reserved from the start.

Fix 5: Animate with transform

/* Bad: causes layout shift */
.box { transition: top 0.3s; }

/* Good: no layout shift */
.box { transition: transform 0.3s; }
Enter fullscreen mode Exit fullscreen mode

Working with WordPress?

On WordPress, CLS usually comes from themes, page builders, sliders, lazy-loading plugins and ad scripts. I wrote a separate step-by-step guide for that: How to Fix Cumulative Layout Shift (CLS) on WordPress.

Step 5: Verify the result

Run Lighthouse again and compare the lab CLS. Field data in PageSpeed Insights and Search Console updates over a 28-day window, so give it a few weeks before judging the real-user score.

Quick CLS checklist

  • [ ] All images and videos have width and height
  • [ ] Ads, iframes and embeds have reserved space
  • [ ] Fonts are preloaded with a good fallback
  • [ ] No banners injected above content
  • [ ] Animations use transform and opacity only
  • [ ] CLS is 0.1 or less in PageSpeed Insights

I'm Zahid Awais, an SEO expert and link building specialist. I help businesses improve technical SEO, content and backlinks. You can find more SEO guides and free tools at zahidawais.com.

Top comments (0)