---
title: CLS Explained: Cumulative Layout Shift (and how to fix it)
description: CLS measures the most annoying thing on the web: the page jumping around as it loads. Here's what it is, what counts as good, and how to stop your layout from dancing.
canonical: https://watchfor.io/blog/cls-explained
---

# CLS Explained: Cumulative Layout Shift (and how to fix it)

2026-01-27 · WatchFor Team · Performance · performance, core-web-vitals, seo

CLS measures the most annoying thing on the web: the page jumping around as it loads. Here's what it is, what counts as good, and how to stop your layout from dancing.

You've felt it: you go to tap a button, an ad or image loads above it, everything jumps down, and your tap lands on the wrong thing. That maddening jumpiness has a name and a number — **CLS** — and it's one of the three [Core Web Vitals](/blog/core-web-vitals-explained). Here's how to tame it.

## What CLS measures

**CLS (Cumulative Layout Shift)** measures how much the page's content **unexpectedly moves around** while it loads. Every time something already on screen shifts position, that's a layout shift, and CLS adds them up into a score.

Unlike the other vitals, CLS isn't measured in seconds — it's a unitless score. Lower is better; zero means nothing moved.

## What counts as good

| CLS | Verdict |
| --- | --- |
| ≤ 0.1 | Good |
| 0.1 – 0.25 | Needs improvement |
| Over 0.25 | Poor |

Aim for **0.1 or below**. Above that, users start noticing the jumpiness.

## What causes layout shift

CLS almost always comes from elements that take up space *after* the page has already started rendering:

| Cause | The shift it creates |
| --- | --- |
| **Images without dimensions** | The image loads and shoves content down |
| **Ads / embeds** | An ad slot fills in and pushes everything around |
| **Web fonts** | Text re-flows when a custom font swaps in |
| **Injected banners** | A cookie/notification bar appears at the top |
| **Dynamic content** | Content inserted above what the user is reading |

## How to fix it

The golden rule: **reserve the space before the content arrives.**

1. **Always set width and height on images and video** (or use `aspect-ratio`). Then the browser reserves the right space, and the image fills it without shoving anything.
2. **Reserve space for ads and embeds.** Give ad slots a fixed size up front so filling them doesn't move the page.
3. **Handle fonts carefully.** Use `font-display` settings and size-matched fallbacks so swapping to a custom font doesn't re-flow text. (See [web font performance](/blog/web-font-performance).)
4. **Insert dynamic content below the fold or in reserved space** — never shove it above what someone's already reading.
5. **Avoid banners that push content.** If you must show one, overlay it or reserve its space.

> **The one-line fix for most CLS:** give everything that loads late a **reserved size**. Images, ads, embeds — if the browser knows how big they'll be, nothing jumps when they arrive.

## Why it matters beyond annoyance

CLS isn't just irritating — it causes real mistakes (tapping the wrong button, mis-clicks on the wrong link) and it's a [Google ranking signal](/blog/core-web-vitals-explained). A jumpy page frustrates users *and* hurts SEO.

## The bottom line

| | In one line |
| --- | --- |
| **What** | How much the layout unexpectedly moves while loading. |
| **Good** | 0.1 or below. |
| **Cause** | Elements that take space *after* render — images, ads, fonts. |
| **Fix** | Reserve space up front (dimensions, `aspect-ratio`, sized slots). |

CLS is the web's most fixable annoyance: reserve space for anything that loads late, and the page stops dancing. Your users stop mis-tapping, and your Core Web Vitals go green.

Related: [Core Web Vitals explained](/blog/core-web-vitals-explained), [web font performance](/blog/web-font-performance); test with the free [Core Web Vitals checker](/core-web-vitals-checker).

---

Canonical page: https://watchfor.io/blog/cls-explained · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
