Skip to content
WL Tech Logo

How to Fix Cumulative Layout Shift (CLS) - The Plain English Guide

Christopher Welshby Christopher Welshgeneral3294 words

How to Fix Cumulative Layout Shift (CLS) - The Plain English Guide

You've probably experienced it yourself. You open a web page on your phone, the text loads, you go to tap a link, and suddenly the whole page jumps and you've clicked the wrong thing. Maybe an image just appeared out of nowhere and pushed everything down. Maybe a banner slid in from the top and shoved the paragraph you were reading off the screen.

That jumping, that jarring movement, that is what Google calls Cumulative Layout Shift. And Google measures it as one of its three Core Web Vitals, the metrics it uses to judge how good your website feels to real visitors.

Here is the good news: of the three Core Web Vitals (LCP, CLS, and INP), CLS is usually the easiest one to fix. Most CLS problems come down to a handful of causes, and most of the fixes are genuinely one-line changes. You do not need to restructure your whole site. You need to tell your browser how big things are going to be before they arrive.

I'm going to walk through what CLS is, what causes it, what scores you need to hit, and the specific fixes that work. No jargon, no assumptions about your technical background.

What is Cumulative Layout Shift (CLS)?

CLS measures visual stability. Specifically, it measures how much the visible elements on your page move around while the page is loading and being used.

Every time something on your page shifts position unexpectedly, that is a layout shift. Google calculates a score for each shift based on two things:

  • How far the element moved (distance fraction)
  • How much of the viewport was affected (impact fraction)

Add up all the individual shifts across the page's lifetime and you get your Cumulative Layout Shift score. The lower, the better.

A page with a CLS of 0 is rock solid. Nothing moves. Everything appears exactly where it is going to stay. A page with a CLS of 0.3 is a mess. Buttons jump, text reflows, images pop in and shove content around.

Google has been measuring CLS since 2020, and it became a formal ranking factor as part of the Core Web Vitals rollout. In 2024, Google refined the metric to cap the score at the worst individual layout shift, rather than accumulating shifts indefinitely. This means pages with a lot of small shifts (like infinite scroll) are not unfairly penalised, but a single large shift can still tank your score.

Why CLS matters for your business

Beyond the SEO angle (Google does reward pages that pass Core Web Vitals, and slow websites lose customers for reasons that go well beyond rankings), layout shift is a direct usability problem.

Research from the Chrome team has shown that layout shift is one of the most frustrating experiences for mobile users. When a page jumps, people miss their taps. They hit the wrong button. They lose their place in an article. On an e-commerce site, that can mean someone accidentally clicks the wrong product variant or, worse, abandons the page entirely because it feels broken.

For small businesses, this is not an abstract concern. If your contact page jumps every time someone tries to tap your phone number, that is a lost enquiry.

CLS thresholds: what score do you need?

Google defines three bands for CLS, based on real-user data collected through the Chrome User Experience Report (CrUX):

  • Good: less than 0.1 — Your page is visually stable. Visitors are not experiencing annoying jumps.
  • Needs improvement: 0.1 to 0.25 — There are noticeable shifts. Google will flag this in Search Console and your page may not qualify for the "Good" Core Web Vitals status.
  • Poor: greater than 0.25 — Your page is jumping enough to genuinely frustrate users. Google will report this as a poor experience and it can hold back your rankings.

These thresholds are based on the 75th percentile of real-user visits to your page. That means if 75% of your visitors have a CLS experience below 0.1, your page is considered "good." It is not about your best-case scenario. It is about what most of your visitors actually experience.

If you have run a Lighthouse audit and seen a CLS score, that is a lab-based simulation. It is useful, but the real numbers that matter for SEO come from CrUX field data, which is what Google uses for ranking signals.

What causes layout shift?

Most CLS problems fall into four categories. I will cover each one and the specific fix.

1. Images and embeds without dimensions

This is the single most common cause of CLS issues, and it accounts for the majority of the problems I see in website audits.

When your browser loads a page, it starts laying out content before images finish downloading. If you have not told the browser how big the image is going to be, it reserves zero space for it. The text flows as if the image does not exist. Then, a second or two later, the image arrives, the browser suddenly knows it is 800 pixels tall, and it shoves everything below it down the page.

That shove is a layout shift. And if you have five images on the page without dimensions, you get five shifts.

The same thing happens with embedded videos, Instagram posts, Twitter feeds, Google Maps, and any other iframe-based embed. The browser does not know how much space to reserve, so it reserves none, and the content jumps when the embed loads.

The fix: Give every image and embed explicit width and height attributes in your HTML.

<img src="team-photo.jpg" width="800" height="600" alt="Our team">

That is it. The browser now knows to reserve a 800x600 box. When the image loads, it fills the space that was already set aside. Nothing moves.

For responsive images (where the image scales to fit the screen), you still need width and height attributes. Modern browsers use them to calculate the aspect ratio, then scale the reserved space proportionally. You can also use the CSS aspect-ratio property:

.hero-image {
  aspect-ratio: 4 / 3;
  width: 100%;
  height: auto;
}

This tells the browser "this element will always be in a 4:3 ratio," so it reserves the right amount of vertical space regardless of screen width.

For embeds (YouTube videos, maps, social posts), the same principle applies. Wrap the embed in a container with a defined aspect ratio or min-height so the space is reserved before the embed loads.

2. Ads and dynamically injected content without reserved space

If you run ads on your site, whether that is Google AdSense, display ads from a network, or even your own promotional banners that load dynamically, this one is for you.

Ad scripts typically work like this: the page loads, the ad script runs, it figures out which ad to show, and then it injects the ad into your page. If you have not reserved space for that ad, the moment it appears, everything below it gets pushed down.

This is particularly brutal for CLS because ads are often placed near the top of the page or inline with content. A single ad injection can shift the entire visible area.

The fix: Reserve space for the ad slot before the ad loads. Give the ad container a min-height based on the expected ad size.

.ad-slot {
  min-height: 250px;
  width: 100%;
}

If you know the ad will be 300x250, reserve at least 250 pixels of height. If the ad fills the slot, no shift. If no ad fills, you have an empty box, but nothing jumped. You can style the empty state with a background colour or a placeholder so it does not look broken.

Google's own AdSense documentation recommends this approach. The Publisher Ads Lab has specific guidance on minimising layout shift from ads, and the core recommendation is always the same: reserve the space.

3. Content injected above existing content

This one is subtle but common. It happens when new content appears above content that has already loaded, pushing it down.

The classic example is a notification banner. The page loads, the user starts reading, and then a cookie consent banner or a newsletter signup bar slides in at the top of the page. Everything below it shifts down. That is a layout shift.

Other examples:

  • A "back to top" button that appears after scroll and pushes content
  • A sticky header that changes height when you scroll
  • A chat widget that expands and shifts the page layout
  • Dynamically loaded related articles that appear above the current content

The fix: Do not inject content above existing content unless you have reserved space for it from the start.

If you know you are going to show a cookie banner, reserve the space in your initial layout. Set a min-height on the banner container so the page always accounts for it, even before the banner appears.

For sticky headers that change size, use position: fixed or position: sticky so the header occupies its own layer and does not push page content when it changes.

For chat widgets, make sure they are positioned fixed or absolute so they overlay the page rather than inserting into the document flow and shifting content.

4. Web fonts causing text to reflow

This one is a bit more technical, but it affects a lot of sites.

When a page uses a custom web font (anything that is not a default system font like Arial or Helvetica), the browser has to download the font file before it can render the text in that font. What happens during that download depends on your font-loading strategy.

If the browser shows nothing until the font loads (known as FOIT, or Flash of Invisible Text), your CLS might be fine because no text moves, but visitors stare at a blank space while waiting. That is bad for LCP, the loading-speed metric.

If the browser shows text in a fallback system font and then swaps to the web font once it loads (known as FOUT, or Flash of Unstyled Text), the text is visible sooner, but when the font swaps, the new font might be wider or taller than the fallback. The text reflows. Lines break differently. Elements shift. That is a layout shift.

The fix: There are two approaches, and you can combine them.

First, use font-display: swap in your @font-face declaration. This tells the browser to show the fallback font immediately and swap when the web font is ready. It does not eliminate the shift entirely, but it gets text on screen fast and the swap is usually minor if your fallback font is well-matched.

@font-face {
  font-family: "MyCustomFont";
  src: url("/fonts/myfont.woff2") format("woff2");
  font-display: swap;
}

Second, preload your font files so they download early, reducing the window where the fallback font is visible and minimising the reflow when the swap happens.

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

Third, and this is the most effective fix, choose a fallback font that is metrically similar to your web font. Google Fonts and other font services often list compatible system fonts. If your fallback font has the same character widths as your web font, the swap produces almost no visible shift. Tools like Font Style Matcher (open source, by Jamie Appleseed) can help you tune your fallback font's size and spacing to match your web font closely.

How to measure your CLS score

You cannot fix what you cannot measure. Here are the three tools I use to check CLS, in order of how I use them.

Google PageSpeed Insights

This is the quickest way to check any page. Go to pagespeed.web.dev, type in your URL, and you get a report in about 30 seconds.

PageSpeed Insights gives you two sets of data:

  • Field data (from CrUX): Real-user CLS scores from the last 28 days, broken down by mobile and desktop. This is the data Google uses for rankings.
  • Lab data (from Lighthouse): A simulated page load run from a server. This gives you a single CLS score for that moment and identifies specific elements that caused shifts.

If your field data shows CLS above 0.1, you have a problem that real users are experiencing. If your lab data shows CLS above 0.1 but field data is fine, you may have an intermittent issue or the lab simulation hit a case that real users do not often encounter.

Lighthouse

Lighthouse is the engine behind PageSpeed Insights' lab data, but you can also run it directly in Chrome. Open Chrome DevTools (right-click, Inspect), go to the Lighthouse tab, and run an audit.

The advantage of running Lighthouse locally is that it gives you a detailed breakdown of which elements shifted and by how much. Look at the "Avoid large layout shifts" audit in the report. It will list the specific elements that caused shifts and the contribution of each to your total CLS score. That tells you exactly what to fix.

Google Search Console

Search Console has a dedicated Core Web Vitals report. It shows you which URLs on your site have CLS problems, grouped by severity (Poor, Need improvement). This is based on CrUX field data, so it reflects what real visitors are experiencing.

The Search Console report is useful because it shows you the scope of the problem across your whole site, not just one page. If you have 50 URLs flagged as "Poor" for CLS, you have a systemic issue, probably images without dimensions across your templates.

One caveat: Search Console data lags by about 28 days. If you make a fix today, you will not see the effect in Search Console for roughly a month. Use PageSpeed Insights for a faster check after making changes.

CLS is the easiest Core Web Vital to fix

I want to be clear about this because it surprises people. Of the three Core Web Vitals, CLS is typically the most straightforward to fix.

LCP (loading speed) often requires work on your server, your images, your CDN, and your critical rendering path. INP (interactivity) can require refactoring JavaScript, breaking up long tasks, and reducing third-party scripts. Both can involve structural changes to how your site is built.

CLS, by contrast, is mostly about telling the browser the size of things before they load. Add width and height to your images. Reserve space for your ad slots. Use font-display: swap on your web fonts. These are small, targeted changes that do not require rebuilding your site.

In my audits, I regularly see CLS scores drop from 0.25 to under 0.1 after adding dimension attributes to images and reserving space for one or two embeds. That is a move from "poor" to "good" with changes that take a developer under an hour.

That said, "easy" does not mean "obvious." If you do not know what CLS is or what causes it, you would not think to add height attributes to your images. That is the whole point of this guide.

Common CLS mistakes I see in audits

I have run hundreds of website audits through WL Tech, and the same CLS problems come up repeatedly. Here are the ones I see most often:

Responsive images without aspect ratios. People set width: 100% on images for mobile responsiveness but forget to set a height or aspect ratio. The browser cannot calculate the vertical space, so it reserves none. Every image causes a shift when it loads.

WordPress themes that strip dimensions. Some older WordPress themes and page builders remove width and height attributes from images, ostensibly for responsive design. This was common practice years ago before browsers supported aspect-ratio from dimensions. If your theme does this, your CLS is probably suffering.

Late-loading cookie banners. Cookie consent tools that appear after the page has loaded, pushing content down, are a frequent culprit. The fix is to reserve the banner's space in your initial layout or position it as an overlay that does not affect document flow.

YouTube embeds without containers. A bare YouTube iframe with no wrapper will cause a layout shift when it loads. Wrap it in a container with a 16:9 aspect ratio and the problem disappears.

Font swaps with mismatched fallbacks. If your web font is a condensed sans-serif and your fallback is Times New Roman, the swap is going to be dramatic. Match your fallback font's metrics to your web font and the shift becomes negligible.

The checklist: fixing CLS on your site

If you want to work through this systematically, here is the order I recommend:

  1. Run your page through PageSpeed Insights. Note your CLS score (both field and lab).
  2. If lab CLS is above 0.1, look at the "Avoid large layout shifts" audit to see which elements are shifting.
  3. Add width and height attributes to every image on the page. For responsive layouts, use aspect-ratio in CSS.
  4. Wrap every iframe embed (YouTube, Maps, social posts) in a container with a defined aspect ratio.
  5. Add min-height to any ad slots or dynamically loaded content areas.
  6. Check that cookie banners, chat widgets, and notification bars are either reserved space or positioned outside the document flow.
  7. Add font-display: swap to your @font-face declarations and preload your main font files.
  8. Re-run PageSpeed Insights and check the lab CLS score. It should be under 0.1.
  9. Wait 28 days and check Search Console to confirm the field data has improved.

Most of these are one-line changes per element. The whole checklist can be completed in an afternoon for a typical small business website.

Getting help with CLS

If you have read through this and thought "I understand the problem but I do not want to touch my website's code," that is completely fair. You are running a business, not learning front-end development.

That is where I come in. I run WL Tech, and I offer a free website audit that checks your Core Web Vitals (including CLS), identifies exactly what is causing layout shifts on your pages, and tells you what to fix and in what order.

You can get your free audit at wltech.pro. No obligation, no sales call, no retainer. You get a report showing your scores, your problems, and your options. If you want me to fix the issues, I offer a $250 Quick Fix for the top three problems or a $500+ Full Fix for everything. If you just want the report to hand to your own developer, that is fine too.

CLS is the Core Web Vital I fix most often because it is the most common problem and the most rewarding to resolve. A page that was jumping around for every visitor becomes rock solid, and the score moves from red to green. It is a small change with a real impact on how your site feels and how Google judges it.

Related reading


About the author

Christopher Welsh is a systems engineer and founder of WL Tech, based in the Scottish Borders. He spent years as a sysadmin and DevOps engineer before building WL Tech to help small businesses fix their websites. He specialises in website performance audits, Core Web Vitals fixes, and technical SEO. No retainers, no jargon, just clear analysis and practical fixes.

Get a free website audit →

Want to check your own website?

Run our free 60-second audit to see how your site scores on speed, SEO, and AI visibility.

Start Free Audit →

We use only essential cookies to make this site work - no tracking, no ads. See our privacy policy.