<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zahid Awais</title>
    <description>The latest articles on DEV Community by Zahid Awais (@zahidawais).</description>
    <link>https://dev.to/zahidawais</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4217837%2F9703283c-dadf-4523-b867-874a754a959e.png</url>
      <title>DEV Community: Zahid Awais</title>
      <link>https://dev.to/zahidawais</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zahidawais"/>
    <language>en</language>
    <item>
      <title>How to Find and Fix Layout Shift (CLS) Using Chrome DevTools: A Practical Guide</title>
      <dc:creator>Zahid Awais</dc:creator>
      <pubDate>Fri, 30 Oct 2026 18:30:23 +0000</pubDate>
      <link>https://dev.to/zahidawais/how-to-find-and-fix-layout-shift-cls-using-chrome-devtools-a-practical-guide-4bka</link>
      <guid>https://dev.to/zahidawais/how-to-find-and-fix-layout-shift-cls-using-chrome-devtools-a-practical-guide-4bka</guid>
      <description>&lt;p&gt;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 &lt;strong&gt;layout shift&lt;/strong&gt;, and Google measures it with a Core Web Vital called &lt;strong&gt;Cumulative Layout Shift (CLS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A good CLS score is &lt;strong&gt;0.1 or less&lt;/strong&gt;. Anything above 0.25 is considered poor, and it can hurt both user experience and your rankings.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually causes layout shift?
&lt;/h2&gt;

&lt;p&gt;In my SEO audits, almost every CLS problem comes from one of these five things:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Step 1: Measure CLS before you change anything
&lt;/h2&gt;

&lt;p&gt;Run the page through &lt;strong&gt;PageSpeed Insights&lt;/strong&gt; or Lighthouse in DevTools (&lt;code&gt;F12&lt;/code&gt; → &lt;strong&gt;Lighthouse&lt;/strong&gt; → Analyze page load). Note two numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Field data (real users)&lt;/strong&gt;: what Google actually uses for ranking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lab data&lt;/strong&gt;: useful for testing your fixes quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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 &lt;a href="https://zahidawais.com/free-seo-audit/" rel="noopener noreferrer"&gt;free SEO audit tool&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Find the shifting elements in DevTools
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open DevTools and press &lt;code&gt;Ctrl + Shift + P&lt;/code&gt; (&lt;code&gt;Cmd + Shift + P&lt;/code&gt; on Mac).&lt;/li&gt;
&lt;li&gt;Type &lt;strong&gt;Rendering&lt;/strong&gt; and open the Rendering panel.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Layout Shift Regions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Reload the page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every element that moves will flash &lt;strong&gt;blue&lt;/strong&gt;. Now you can see exactly what is jumping instead of guessing.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Step 3: Log layout shifts with a small script
&lt;/h2&gt;

&lt;p&gt;Sometimes shifts happen after scrolling or clicking, and they are hard to catch visually. Paste this into the Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hadRecentInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Layout shift:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;  moved:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;layout-shift&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buffered&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Apply the fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fix 1: Always set image dimensions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hero.webp"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"630"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Hero image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern browsers use these attributes to calculate the aspect ratio before the image loads. Keep it responsive with CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fix 2: Reserve space for ads and embeds
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.ad-slot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.video-embed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fix 3: Load fonts without big jumps
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preload"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/fonts/inter.woff2"&lt;/span&gt; &lt;span class="na"&gt;as=&lt;/span&gt;&lt;span class="s"&gt;"font"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"font/woff2"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@font-face&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Inter'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'/fonts/inter.woff2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'woff2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;size-adjust&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choosing a fallback font with similar metrics (or using &lt;code&gt;size-adjust&lt;/code&gt;) keeps the swap almost invisible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix 4: Never insert content above existing content
&lt;/h3&gt;

&lt;p&gt;Cookie banners and notification bars should be &lt;strong&gt;overlays&lt;/strong&gt; (&lt;code&gt;position: fixed&lt;/code&gt;) or have their space reserved from the start.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix 5: Animate with transform
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Bad: causes layout shift */&lt;/span&gt;
&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Good: no layout shift */&lt;/span&gt;
&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Working with WordPress?
&lt;/h2&gt;

&lt;p&gt;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: &lt;a href="https://zahidawais.com/fix-cls-wordpress/" rel="noopener noreferrer"&gt;How to Fix Cumulative Layout Shift (CLS) on WordPress&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Verify the result
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick CLS checklist
&lt;/h2&gt;

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




&lt;p&gt;&lt;em&gt;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 &lt;a href="https://zahidawais.com" rel="noopener noreferrer"&gt;zahidawais.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>performance</category>
      <category>wordpress</category>
    </item>
  </channel>
</rss>
