Cumulative Layout Shift: how to find and fix what moves
CLS measures how much visible content jumps around unexpectedly. Aim for 0.1 or less. The element that moved usually isn't the cause: something above it loaded late and pushed it. Reserve space for images, ads and late content before they arrive.
What CLS measures
Cumulative Layout Shift is the Core Web Vital for visual stability. It's what makes you tap the wrong button because the page moved at the last moment.
| Good | Needs improvement | Poor |
|---|---|---|
| 0.1 or less | Over 0.1, up to 0.25 | Over 0.25 |
- It's a score, not a time. Each shift is scored on how much of the viewport moved and how far.
- It takes the worst burst. Shifts less than a second apart are grouped, up to 5 seconds, and CLS is the highest group's total.
- It covers the whole visit. Shifts can happen long after load, so a test that stops at load can miss them.
- Expected shifts don't count. A shift within 500 ms of a click, tap or key press is left out. Scrolling doesn't count as that kind of input.
The score Google uses comes from real Chrome visitors at the 75th percentile, which you can see in Search Console's Core Web Vitals report or PageSpeed Insights.
How to find the shift
1Run the snippet 2 minutes
Load the page, open DevTools (F12), go to the Console and paste this, then scroll down the page:
// Logs each unexpected layout shift and what moved
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.hadRecentInput) continue;
console.log(entry.value.toFixed(4), Math.round(entry.startTime) + ' ms', entry.sources.map((s) => s.node));
}
}).observe({ type: 'layout-shift', buffered: true });
Each line shows the shift's score, when it happened and the elements that moved. These are single shifts, so they won't add up to the page's CLS.
2Use the Performance panel 3 minutes
Record a page load in the Performance tab. It marks layout shifts on the timeline, so you can see what loaded just before each one.
Test as a first-time visitor on a phone-sized screen. Cached images and fonts can hide shifts, and cookie banners only appear on a first visit.
The usual causes
| Cause | What you'll see |
|---|---|
| Images with no size | Text jumps down when the image arrives |
| Ads and embeds | A slot grows or collapses after load |
| Content added late | A banner or block appears above what you're reading |
| Web fonts | Text reflows when the font swaps in |
| Layout animations | Animating top, left or margin moves other elements |
How to fix them
- Images and video: set
widthandheight, or use CSSaspect-ratio. - Ads and embeds: give the slot a
min-heightbased on its smallest likely size, and keep the space if nothing fills it. - Late content: use a placeholder, put it lower on the page, or load it when someone asks with a button.
- Web fonts: preload key fonts, pick a close fallback and consider
font-display: optional. - Animations: use
transform, which doesn't move other elements. - Back and forward navigation: keep pages eligible for the back/forward cache, so they're restored without shifting.
<img src="/photo.webp" width="800" height="600" alt="...">
<style>
.ad-slot { min-height: 250px; }
.video { aspect-ratio: 16 / 9; }
</style>
How crawlers report this
These labels come from PageSpeed data, so they can change between versions.
| Screaming Frog | Sitebulb | What it means |
|---|---|---|
| PageSpeed: Layout Shift Culprits | No direct match | Something on the page is likely causing shifts. |
| Images: Missing Size Attributes | Add dimensions to images | Images have no set size, so the browser can't reserve space. |
| PageSpeed: Font Display | Ensure text remains visible during webfont load | Fonts may change how text appears as they load. |
Hard to explain to a developer?
See what moved and why
SEOSnip's Speed tab records the layout shifts your browser saw as you used the page. It's not field data, so use it to find the cause. You get:
- Each shift with its score and time, worst first
- The elements that moved, how far, and a highlight on the page
- A diagram of the move, with the likely cause where one can be found
- A ticket for one shift or the whole page, with that evidence attached