
What is Cumulative Layout Shift (CLS) and How to Optimize For It
Aug 23, 2024
5 min read
When your site jumps around unexpectedly while someone’s trying to use it, that’s Cumulative Layout Shift (CLS). And it’s a problem.
Out of the three Core Web Vitals - LCP, INP, and CLS - CLS is the one that has the least to do with speed. It’s about stability. And it’s one of the easiest ways to frustrate your users without even realizing it. This guide covers what CLS actually is, how it’s measured, where it tends to go wrong, and how to fix the most common issues - step by step.
What is CLS, really?
CLS is a metric that tracks how much the visible elements on your page unexpectedly move around. It’s calculated based on how far things shift and how much of the screen is affected.
In simpler terms:If stuff moves when it shouldn’t - you’re getting dinged for it.
Every layout shift gets a score. Google adds them up to give your page a total CLS value. The formula is based on:
Impact fraction: how much of the viewport was affected
Distance fraction: how far the element moved
Here’s the scoring scale:
Good: CLS of 0.1 or less
Needs improvement: 0.1–0.25
Poor: Over 0.25
If you’re scoring high, your users are probably rage-clicking and bouncing before they even get to your CTA.
Why CLS actually matters
Let’s say a user is about to tap a “Buy Now” button. Then the layout shifts and they accidentally tap “Cancel” or some unrelated link. That’s a conversion lost - and probably a user too.
CLS isn’t just about meeting Google’s standards. It’s about basic usability:
Preventing misclicks
Maintaining reading position
Keeping interactions predictable
Also worth noting: Google uses CLS as part of its ranking algorithm. So yes, a bad CLS can hurt your SEO too.
How to measure CLS (with the right tools)
You can’t fix what you can’t see. These are the best tools for tracking CLS:
1. Google PageSpeed Insights
Plug in your URL
Get lab + field data
CLS score is right there in the Core Web Vitals section
Bonus: lists specific elements causing layout shifts
2. Chrome DevTools
Open your site → Right-click → Inspect → Performance tab
Hit record, interact with the page, stop recording
Look for layout shifts in the summary
Great for real-time debugging
3. Web Vitals Chrome Extension
Quick visual check in your browser
See CLS, INP, and LCP in real time
No setup needed
4. Google Search Console
Go to the Core Web Vitals report
View CLS issues across all URLs
Field data only (from actual users)
5. Lighthouse
Integrated into DevTools
Offers both page audit and CLS data
Useful for finding shifts in simulated conditions
What causes CLS - and how to fix each one
Let’s walk through the most common causes of layout shifts and how to eliminate them.
01. Images without dimensions
The problem:If an image doesn’t have width/height set, the browser doesn’t know how much space to allocate - so the layout shifts when the image finally loads.
How to spot it:
Inspect your page
Check if <img> tags are missing width and height
Use PSI or Web Vitals extension to confirm
How to fix it:Set dimensions either inline or in CSS:
<img src="example.jpg" width="600" height="400" alt="Example image">
For responsive layouts:
img { width: 100%; aspect-ratio: 3 / 2; }
02. Ads, embeds, and iframes without reserved space
The problem:Ad slots, YouTube embeds, or iframes are loaded late and push everything down.
How to spot it:
Look for late-loading elements
Use DevTools to simulate slow network and watch layout changes
How to fix it:Always define space ahead of time:
<iframe src="example.html" width="600" height="400"></iframe>
Or use a styled placeholder:
.ad-slot { width: 300px; height: 250px; background-color: #eee; }
If you’re lazy-loading, make sure space is still reserved.
03. Web fonts causing FOUT/FOIT
The problem:Fonts load slowly. The browser either:
Shows fallback font → then swaps to custom (FOUT)
Shows nothing → then reveals styled font (FOIT)
Either way, text moves when it shouldn’t.
How to spot it:
Watch for flash or reflow when fonts load
Use DevTools or WebPageTest to analyze font loading behavior
How to fix it:
Use font-display: swap to show fallback immediately:
@font-face { font-family: 'MyFont'; src: url('myfont.woff2') format('woff2'); font-display: swap; }
Preload key fonts:
<link rel="preload" href="myfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">
Pick fallback fonts that match the size of your custom fonts as closely as possible
04. Dynamic content (banners, popups, etc.) injected above the fold
The problem:Banners or modals get injected into the top of the page after load. That pushes everything down.
How to spot it:
Load your page slowly and watch for sudden shifts
Pay attention to anything that appears after initial paint
How to fix it:
Reserve space in advance, like this:
.banner-placeholder { height: 250px; background: #f5f5f5; }
Avoid inserting new DOM elements above existing content
If content must be added dynamically, animate it smoothly:
.new-content { opacity: 0; transition: opacity 0.3s ease-in; } .new-content.loaded { opacity: 1; }
05. FOUC (Flash of Unstyled Content)
The problem:Page renders before CSS is loaded. Styles snap in afterward, shifting everything.
How to spot it:
Reload and watch for a flicker of unstyled text
Use DevTools to see how long CSS takes to load
How to fix it:
Inline critical CSS:
<style> body { font-family: Arial, sans-serif; background: #fff; } </style>
Minify and combine CSS
Preload key stylesheets:
<link rel="preload" href="styles.css" as="style">
Use a fast CDN and caching
06. Incorrect DOM order
The problem:The visual layout doesn't match the HTML structure. When elements load or reflow, they move other content around.
How to spot it:
Inspect with DevTools
Compare what’s in your DOM to what you see visually
How to fix it:
Keep the DOM order logical and consistent:
<header>...</header> <main>...</main> <footer>...</footer>
Use Flexbox or Grid to control layout without rearranging the DOM:
.container { display: flex; flex-direction: column; }
Avoid unnecessary DOM manipulation during load
Want to go deeper? Try these advanced techniques
1. Prioritize above-the-fold content
Only load what’s necessary to render the initial viewport. Defer or lazy-load everything else. Use:
<link rel="preload" href="critical.css"> <script src="noncritical.js" defer></script>
2. Use a CDN
Faster asset delivery = fewer delays = less layout shifting. Make sure fonts, images, and CSS load quickly from the closest server.
<link rel="stylesheet" href="https://cdn.example.com/styles.css">
3. Monitor CLS continuously
Don’t treat CLS like a one-time fix.
Use tools like Search Console and RUM dashboards to track changes over time
Set up alerts if CLS spikes
Run regular audits when shipping new features
Wrapping up
CLS might not get as much attention as LCP or INP - but it’s just as important.
It impacts your users directly. It impacts your rankings. And most of the time, fixing it doesn’t require a complete rebuild - just smarter implementation and a bit of attention to detail.
Start by identifying your top offenders: images, iframes, ads, fonts. Fix them systematically. Monitor and repeat.
Because in the end, CLS isn’t about passing a test. It’s about building a site that feels reliable, polished, and stable from the second it loads.
Your users will notice. And so will Google.