How to Fix Cumulative Layout Shift (CLS): Every Cause and Solution Explained
Cumulative Layout Shift (CLS) measures unexpected page movement that frustrates users and hurts your Google rankings. Learn every common cause of high CLS and exactly how to fix each one with real code examples.
The Most Annoying Problem on the Web
You're reading an article. You're about to tap a link. Then the page shifts, an ad loads above, and you accidentally tap something else entirely. Or you're filling out a form and the whole page jumps because a font loaded and changed the text size.
That's layout shift. And Google hates it as much as your users do.
Cumulative Layout Shift (CLS) is one of the three Core Web Vitals that directly affect your search rankings. Unlike LCP and INP which measure speed, CLS measures visual stability. A page that loads fast but jumps around will still get penalized.
The good news? CLS is the most preventable Core Web Vital. Almost every cause has a straightforward fix. Let's go through all of them.
What Exactly Is CLS?
CLS measures how much visible content unexpectedly shifts during the page lifecycle. Every time an element moves after it's already been rendered, the browser calculates an impact score based on how much of the viewport was affected and how far things moved.
The final CLS score is the largest burst of layout shifts that happens within a short window. Google uses a "session window" approach: it groups shifts that occur within 1 second of each other (with a 5-second max window) and takes the worst session.
Google's thresholds:
These apply at the 75th percentile of real user visits. So 75% of your users need to experience a CLS of 0.1 or less for Google to consider it "good."
A CLS of 0.1 is actually a lot of movement. If 10% of the viewport shifts by 10% of the screen height, that's a CLS of 0.01. To hit 0.25, something significant has to move on the page.
How to Measure Your CLS
CLS is tricky because it depends heavily on how users interact with the page. Scrolling, clicking, and waiting all produce different shift patterns.
Lab tools (Lighthouse, PageSpeed Insights): These simulate a page load without any user interaction. They'll catch shifts that happen during initial load but miss shifts triggered by scrolling or clicking. Lab CLS tends to be lower than real-user CLS.
Field data (CrUX, real user monitoring): This captures what actual users experience, including shifts from lazy-loaded content, scroll-triggered animations, and late-loading ads. This is what Google uses for rankings.
How to check: Run your pages through BulkAudit to see both lab CLS and CrUX field CLS side by side. If your lab CLS is good but field CLS is poor, the shifts are happening after initial load — during user interaction.
Chrome DevTools Performance tab: Record a page load and look for the "Layout Shift" markers in the timeline. Each one shows exactly which elements moved and by how much. This is the best debugging tool for finding specific shifts.
Every Cause of CLS (And How to Fix Each One)
1. Images Without Dimensions
This is the number one cause of CLS on the web. When an image loads without width and height attributes, the browser doesn't know how much space to reserve. It renders the page, then the image loads and pushes everything below it down.
The fix is simple — always set width and height:
Common mistake: Setting only width or only height. You need both for the browser to calculate the aspect ratio and reserve space.
2. Ads, Embeds, and Iframes Without Reserved Space
Third-party embeds (ads, YouTube videos, social media widgets, maps) are notorious for CLS. They load asynchronously and inject content that pushes the page around.
How to fix:
3. Web Fonts Causing Text Reflow
When a custom font loads and replaces the fallback font, text can change size. Lines wrap differently, paragraphs grow or shrink, and everything below shifts.
This is called FOUT (Flash of Unstyled Text) or FOIT (Flash of Invisible Text), and both can cause CLS.
How to fix:
4. Dynamic Content Inserted Without Space
Any content that gets inserted into the page after initial render can cause CLS: cookie banners, notification bars, "subscribe" popups, chat widgets, or dynamically loaded content sections.
How to fix:
5. Late-Loading Content Above the Fold
If your page initially renders with partial content and then fills in more content above the fold (lazy-loaded components, client-rendered sections, async data fetches), each insertion causes a shift.
How to fix:
6. CSS Animations That Trigger Layout
Animations that change width, height, padding, margin, top, left, or other layout properties cause layout shifts. The browser has to recalculate the position of every affected element on each frame.
How to fix:
7. Client-Side Navigation in SPAs
Single-page applications (React, Vue, Angular) that handle navigation client-side can cause CLS when the new page content renders. The old content disappears and new content appears, potentially at a different height.
How to fix:
8. Responsive Design Breakpoint Issues
Sometimes layout shifts occur because media queries change the layout at certain viewport widths. If an element changes from inline to block, or a sidebar appears/disappears based on screen size, it can cause a shift.
How to fix:
9. Tables and Data Grids
Tables that load data asynchronously often cause CLS because the column widths adjust as data arrives. The first few rows might set narrow columns, then a row with longer content arrives and all columns resize.
How to fix:
10. Accordions and Expanding Content
Accordions, "Read more" sections, and expanding FAQs all cause layout shifts when opened because they push content below them down.
How to fix:
Advanced CLS Debugging Techniques
Using the Layout Shift API
You can programmatically detect layout shifts using the PerformanceObserver API. Add this script to your page to log every shift:
This logs each shift event in real-time, showing you exactly which elements shifted, when, and by how much. The hadRecentInput flag tells you whether the shift was user-initiated (which Google excludes from CLS).
Using Chrome DevTools
Using the Rendering Tab
A Practical CLS Fix Workflow
Step 1: Measure. Run your pages through BulkAudit. Check both lab CLS and CrUX field CLS. If field CLS is much worse, shifts are happening during user interaction, not just page load.
Step 2: Identify the shifts. Use Chrome DevTools Performance tab to find each shift. Note which elements are moving and what triggers the movement.
Step 3: Categorize. For each shift, determine the root cause: missing image dimensions? Late-loading ad? Font swap? Dynamic content injection?
Step 4: Fix in order of impact. Fix the largest shifts first. A single image without dimensions in the hero area might account for 80% of your CLS.
Step 5: Verify. Re-run the audit. Lab CLS should improve immediately. Field CLS (CrUX) takes 28 days to fully update since it uses a rolling window.
Step 6: Monitor. Set up scheduled audits in BulkAudit to catch CLS regressions. New deploys, ad changes, and third-party script updates can all reintroduce layout shifts.
CLS Scores by Industry
How does your CLS compare? Here are typical ranges:
If you're above 0.1, you have work to do. If you're above 0.25, it's hurting your rankings.
Frequently Asked Questions
QWhat is a good CLS score?
Google considers CLS good at 0.1 or less, measured at the 75th percentile of real user visits. For the best user experience and competitive advantage, aim for under 0.05. Many well-optimized sites achieve CLS of 0.01 or lower.
QDoes CLS affect SEO rankings?
Yes. CLS is one of the three Core Web Vitals that Google uses as a ranking signal. A poor CLS score (above 0.25) can negatively impact your search rankings, especially in competitive niches where other ranking factors are similar between pages.
QWhy is my CLS different in Lighthouse vs CrUX?
Lighthouse measures CLS during a simulated page load without user interaction. CrUX measures what real users experience over 28 days, including shifts from scrolling, clicking, and interacting with the page. Shifts caused by lazy-loaded images, scroll-triggered ads, and dynamic content only show up in field data.
QDo user-initiated layout shifts count toward CLS?
No. Layout shifts that happen within 500ms of a user interaction (click, tap, keypress) are excluded from CLS. So expanding an accordion, opening a dropdown, or toggling a menu won't hurt your score — as long as the visual change happens promptly after the interaction.
QHow long does it take for CLS improvements to show in CrUX?
CrUX uses a rolling 28-day window of real user data. After you deploy fixes, it takes about 28 days for the old data to fully cycle out. You might see gradual improvement over those 4 weeks as new sessions replace old ones.
QCan CLS be zero?
Yes. A page that reserves space for all content, uses no async-injected elements above the fold, and avoids layout-triggering animations can achieve CLS of exactly 0. Static pages with no dynamic content often have zero CLS.
QWhat causes CLS on mobile but not desktop?
Common causes include: images that have fixed desktop dimensions but become fluid on mobile without aspect-ratio constraints, responsive ads that load different sizes on mobile, web fonts that cause more reflow on smaller viewports (because text wraps more), and mobile-only elements like sticky banners or app install prompts that push content.
QDoes lazy loading cause CLS?
It can. If a lazy-loaded image scrolls into view without dimensions set, it will shift content as it loads. The fix is simple: always set width and height (or use aspect-ratio) on lazy-loaded images so the browser reserves the correct space before the image loads.
QHow do I fix CLS caused by Google Ads?
Google Ads are one of the hardest CLS sources to fix because you don't control the ad creative size. Best approaches: reserve the maximum possible height for each ad slot using min-height, use the CSS contain: layout property on ad containers, avoid ad slots above the fold where possible, and consider using sticky or overlay ad formats that don't push content.
Related Resources
Ready to audit your website?
Use BulkAudit to check up to 25 URLs at once. Get instant Lighthouse scores for Performance, SEO, Accessibility, and Best Practices.
Start Free Audit