You open a page, start reading an article, and suddenly the text jumps down. Your finger was about to tap a link, but now you've clicked an ad instead. That jittery feeling is Cumulative Layout Shift (CLS), one of Google's Core Web Vitals. A high CLS score frustrates visitors and can hurt your search rankings. In this guide, we'll show you how to stop those shifts with practical, beginner-friendly techniques—no computer science degree required.
Think of your webpage as a dining table. You set plates, glasses, and utensils in specific spots. If someone later shoves a large platter in the middle, everything slides. Users get annoyed. CLS works the same way: when elements load after the initial paint, they push already-rendered content around. The result is a poor experience and a low Lighthouse score.
We'll walk through the main causes—images without dimensions, ads that resize, custom fonts that swap, and dynamic content injected late—and show you how to fix each one. By the end, you'll have a stable layout that stays put.
1. What Exactly Causes Layout Shifts and Why Should You Care?
Layout shifts happen when visible elements change their position after the user has already seen them. The browser calculates the layout based on the content it knows about at render time. If new content loads later—say, a banner ad that takes a moment to fetch—the browser must recalculate, pushing other elements down or sideways.
The impact goes beyond annoyance. A high CLS score correlates with lower user engagement. People bounce more, convert less, and associate your site with a shoddy experience. Google uses CLS as a ranking factor in its search algorithm, so a poor score can reduce your organic traffic. For mobile users on slow connections, the problem multiplies because images and scripts load progressively, causing multiple shifts.
Common culprits include:
- Images and videos without explicit width and height attributes
- Ads, embeds, and iframes that resize after loading
- Web fonts that cause invisible text to jump when the font swaps
- Dynamic content injected by JavaScript after the page has painted
- Actions waiting for network responses before updating the UI
Understanding these triggers is the first step to fixing them. In the next section, we'll set up your debugging environment.
2. Prerequisites: What You Need Before You Start Fixing CLS
Before diving into fixes, you need a way to measure CLS. The good news is you don't need expensive tools. Here's what we recommend:
2.1 Browser Developer Tools
Chrome DevTools includes a 'Performance' panel that records layout shifts. Open DevTools (F12), go to the Performance tab, click the record button, reload the page, and stop recording. Look for red bars labeled 'Layout Shift' in the summary. Click one to see the affected region and the shift score.
2.2 Lighthouse Reports
Lighthouse, built into Chrome, audits a page and gives a CLS score. Run it from the 'Lighthouse' tab in DevTools or via Chrome's audit panel. It also suggests specific fixes. For field data, use PageSpeed Insights or the CrUX report in Google Search Console.
2.3 Web Vitals Extension
Install the 'Web Vitals' Chrome extension to see real-time CLS scores as you browse. It shows a floating badge that updates on each page load. This is great for spot-checking after you make changes.
2.4 A Test Page or Staging Environment
Always test fixes on a non-production version of your site. You don't want to accidentally break layout for live users. If you don't have a staging server, use a local development environment or a tool like Ngrok to share a local preview.
2.5 Basic HTML and CSS Knowledge
You don't need to be a coding wizard, but you should be comfortable editing HTML attributes and CSS. We'll provide code snippets you can copy and adapt.
Once you have these tools ready, you can start diagnosing and fixing shifts with confidence.
3. The Core Workflow: Diagnose, Fix, Verify
Fixing CLS follows a repeatable process. We'll break it down into three phases: diagnose, fix, and verify.
3.1 Diagnose: Find the Shifting Elements
Open Chrome DevTools and go to the 'Performance' panel. Record a page load and look for red 'Layout Shift' entries. Click one to see the 'Moved from' and 'Moved to' rectangles. This tells you exactly which element shifted and by how much. Alternatively, use the 'Rendering' tab and enable 'Layout Shift Regions' to see shifting areas highlighted in blue during interaction.
For a quick check, run Lighthouse. It will list 'Avoid large layout shifts' as a diagnostic if your CLS is above 0.1. Click the dropdown to see specific elements that caused shifts.
3.2 Fix: Apply the Appropriate Solution
Once you know the culprit, choose the fix based on the element type:
- Images: Always add
widthandheightattributes in the HTML. For responsive images, usesrcsetandsizesbut still include dimensions. In CSS, setaspect-ratioon containers to reserve space. - Ads: Reserve space with a container that has a fixed width and height. Use CSS
min-heightto prevent collapse. If the ad is slow, show a placeholder of the same size. - Fonts: Use
font-display: swapin your @font-face declaration. This tells the browser to show fallback text immediately and swap when the custom font loads. You can also preload the font using<link rel='preload'>. - Dynamic Content: Inject content only after you know its dimensions. Use CSS
contain: layout style painton containers to isolate shifts. For modals or toasts, use fixed positioning so they don't affect the flow.
3.3 Verify: Confirm the Fix Worked
After applying a change, re-run Lighthouse or record a new performance trace. Compare the CLS score. A good target is 0.1 or less. Also test on a slow network (DevTools has throttling presets) to simulate real-world conditions.
Repeat this cycle for each shift you find. Over time, you'll develop an intuition for what causes jumps and how to prevent them.
4. Tools and Setup: What Works Best in Practice
While browser tools are sufficient, several dedicated tools can streamline the process. Here's a rundown of what we find most useful.
4.1 Lighthouse CI
If you have a continuous integration pipeline, integrate Lighthouse CI. It runs audits on every pull request and prevents CLS regressions. You can set a threshold (e.g., CLS < 0.1) and fail the build if it's exceeded.
4.2 WebPageTest
WebPageTest offers detailed filmstrips and a 'Layout Shift' view. It shows exactly when each shift occurs and how much it contributes to the total CLS. The 'Comparison' feature lets you test before and after fixes side by side.
4.3 Request Map Generator
Sometimes shifts are caused by third-party scripts. Use a request map (like the one in Chrome DevTools or WebPageTest) to see what loads late. Block those scripts in DevTools to see if CLS improves. If so, consider deferring them or loading them asynchronously.
4.4 Content Security Policy (CSP)
A strict CSP can prevent unexpected scripts from injecting content that causes shifts. It's an advanced technique but worth considering for high-traffic sites.
4.5 Real User Monitoring (RUM)
Services like SpeedCurve or Datadog RUM track CLS for actual users. They aggregate scores across devices and connection types, giving you a realistic picture. Use RUM to catch regressions that lab tools might miss.
Choose tools that fit your workflow. For most teams, Chrome DevTools and Lighthouse are enough. Add RUM when you need to monitor at scale.
5. Variations for Different Constraints: When Standard Fixes Don't Fit
Not every site can use the same approach. Here are common constraints and how to adapt.
5.1 You Can't Control Third-Party Content (Ads, Embeds)
If you rely on an ad network that loads dynamic sizes, you can't always reserve exact space. One workaround is to set a min-height on the ad container that matches the most common ad size. For example, if most ads are 300x250, set min-height: 250px. The container will stay that tall even if the ad fails to load. You can also use a placeholder that matches the expected size.
5.2 You Have a Heavy CMS That Injects Late Content
Some CMS platforms add widgets, related posts, or popups after the main content. If you can't modify the CMS code, use CSS to reserve space. For example, if a related posts section appears below the article, set a fixed height on its container. Alternatively, lazy-load it with a placeholder skeleton.
5.3 You Use a Custom Font That Causes a Large Swap
If font-display: swap still causes a visible jump (because the fallback and custom font have different metrics), consider using font-display: optional. This tells the browser to use the fallback if the custom font hasn't loaded after a short timeout. The text won't swap, so no shift occurs. The trade-off is that some users won't see your custom font.
5.4 You Have a Single-Page Application (SPA)
SPAs often shift when routes change or data loads. Use CSS contain on each route container. For async data, show a skeleton loader with fixed dimensions. Avoid updating the DOM in ways that push content around—use transform animations instead of changing layout properties.
Each constraint requires a tailored solution. The key is to always reserve space for late-loading content.
6. Pitfalls and Debugging: What to Check When the Fix Doesn't Work
Even after applying best practices, shifts can persist. Here are common pitfalls and how to debug them.
6.1 Images Without Explicit Dimensions in Responsive Layouts
You added width and height, but the image still shifts. Check if your CSS overrides those attributes. For example, img { width: 100%; } without setting height: auto can cause the browser to ignore the HTML dimensions. The fix is to add height: auto and ensure the aspect ratio is preserved. Better yet, use the aspect-ratio CSS property.
6.2 Ads That Load After User Interaction
Some ad networks delay loading until a user scrolls or clicks. The ad container might be empty initially, then suddenly populate with a tall ad. Reserve space with min-height based on the most common ad size. If the ad is taller, you'll still get a shift, but it's smaller. You can also use a placeholder that matches the median size.
6.3 Web Fonts with Long Load Times
Even with font-display: swap, if the fallback font is very different in size, the swap can cause a shift. Use a fallback font with similar metrics. Tools like Font Style Matcher can help you find a close match. Alternatively, preload the font with <link rel='preload'> and set a short timeout.
6.4 JavaScript That Modifies Layout After Paint
Scripts that insert elements into the DOM after the page has loaded are a major cause. Use requestAnimationFrame to batch DOM changes and avoid triggering multiple layouts. Also, consider using content-visibility: auto on off-screen sections to defer rendering without shifting.
6.5 Cumulative Shifts from Multiple Small Sources
Sometimes no single shift is large, but many small shifts add up. Use the Performance panel to see the total CLS. Fix each small shift until the total drops below 0.1. A shift of 0.05 from an image and 0.05 from an ad can combine to 0.1, so tackle both.
When debugging, isolate variables. Test with third-party scripts blocked. Test with fonts disabled. Narrow down the cause step by step.
7. FAQ: Common Questions About CLS Fixes
Here are answers to questions we often hear from readers.
Q: Does CLS affect mobile more than desktop? Yes, because mobile screens are smaller, so shifts are more noticeable. Also, mobile networks are slower, which increases the chance of late-loading content. Always test on a throttled connection.
Q: Can I fix CLS without changing code? Not really. You need to modify HTML, CSS, or JavaScript. However, some CMS plugins can automatically add dimensions to images. For ads, you might need to work with your ad provider to serve fixed-size units.
Q: What CLS score is 'good'? Google recommends a CLS of less than 0.1. Between 0.1 and 0.25 is 'needs improvement', and above 0.25 is 'poor'. Aim for 0.05 or lower for a comfortable margin.
Q: Will fixing CLS improve my rankings? It's one factor among many. A good CLS alone won't guarantee top rankings, but a poor CLS can hurt you. Plus, it improves user experience, which indirectly boosts engagement metrics.
Q: How long does it take to see CLS improvements in Search Console? Field data in the Core Web Vitals report updates monthly. Lab data from Lighthouse updates immediately. Use lab data to verify fixes, then wait for field data to confirm.
Q: What if my site uses a lot of animations? Animations that change layout properties (like width or height) can cause shifts. Use transform and opacity instead, as they don't trigger layout. Also, set will-change on animated elements to hint the browser.
8. What to Do Next: Your Action Plan for a Jitter-Free Site
Now that you understand the causes and fixes, it's time to act. Here's a concrete next-step plan:
- Audit your current CLS. Run Lighthouse on your top 10 pages. Note the CLS score and the elements causing shifts. Use the Performance panel to get details.
- Fix images first. They are usually the easiest to address. Add width and height attributes to every
<img>tag. For background images, setaspect-ratioon the container. - Reserve space for ads and embeds. Identify all third-party content containers. Add
min-heightandmin-widthbased on expected sizes. Use placeholders if possible. - Optimize font loading. Add
font-display: swapto all custom fonts. Preload the most important fonts. Consider using a fallback font with similar metrics. - Review dynamic content. Audit JavaScript that injects HTML after page load. Refactor to use fixed containers or skeleton loaders. Use
contain: layout style paintto isolate shifts. - Set up monitoring. Add a RUM tool to track CLS in the wild. Set up Lighthouse CI to catch regressions before they go live.
- Iterate. CLS is not a one-time fix. As you add new content, ads, or features, re-check. Make CLS part of your quality checklist.
Your users deserve a stable, predictable page. By following these steps, you'll eliminate those annoying jitters and build trust with every visit. Start with one page today, and work through the list. Your CLS score—and your users—will thank you.
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!