You go to tap “Cancel,” an image loads above it, the whole page lurches down, and your finger lands on “Place order.” That lurch is a layout shift, and Cumulative Layout Shift (CLS) is the metric that scores how much your page jumps around. Good is ≤ 0.1.
See it for yourself
Feel the jank, then pin it
Below is a checkout card. Load it with Reserve space off and watch the product image shove the buttons down right as you'd reach for them. Flip the toggle on and load again — the space is held, nothing moves, and CLS drops to zero:
InteractiveA mis-tap waiting to happen
Checkout
CancelPlace order
CLS score
0.31
Poor
The image pops in and shoves the buttons down — a tap meant for “Cancel” lands on “Place order.”
With no reserved dimensions the image pops in at full height and pushes everything below it. Reserving space fixes it completely.
Still think you'd dodge it in the wild? Prove it. Same physics, but now it's a game — tap Continue reading before the late-loading ad shoves it out from under your finger, then reserve the space and watch your mis-tap count (and the CLS) hit zero:
InteractiveThe mis-tap game — beat the shifting page
Why your favorite site feels broken on a slow connection
You start reading, the page keeps loading, and just as you reach for the link — everything moves. Sound familiar? That jump has a name and a score…
…the metric is Cumulative Layout Shift, and every unexpected move of visible content adds to it while you are trying to interact.
CLS this round
0.00
Without reserved space
no rounds yet
With reserved space
no rounds yet
Play a few rounds without reserved space, then flip the switch and play again. Same page, same ad — but your mis-tap count (and the CLS) goes to zero.
Play a few rounds without reserved space, then flip the switch and play again. Same page, same ad — zero mis-taps.
Definition
What actually counts as a shift
A layout shift happens when a visible element changes its start position between two frames. The key word is visible: a brand-new element appearing doesn't hurt your score by itself — it only counts when it pushes something the user could already see. And shifts the user caused (within 500 ms of a tap or keypress) are excused.
Key idea
CLS measures unexpected movement. Content that moves because the user clicked “Load more” is expected and doesn't count. Content that moves because an ad finally loaded is exactly what it punishes.
The math
How the score is computed
Each shift scores impact fraction × distance fraction. Impact is how much of the viewport the moving content touched (its area before and after, unioned). Distance is how far it moved, relative to the viewport. Drag the slider:
A big element that moves a long way scores worst. The dashed box is the union of the before and after positions — that's the impact fraction.
Those per-shift scores are summed within session windows — a burst of shifts less than 1 s apart, capped at 5 s — and your CLS is the worst window. Thresholds: ≤ 0.1 good, 0.1–0.25 needs work, > 0.25 poor.
The usual suspects
The three big causes — and their fixes
1. Images & videos with no dimensions
Without width/height, the browser reserves zero space until the file loads, then snaps to full size. Always set dimensions (or an aspect-ratio for responsive images):
Third-party content loads late and unpredictably. Reserve a min-height placeholder so the ad fills empty space instead of shoving content. For things like cookie banners, use an overlay that sits on top of the page rather than pushing it. And if a shift truly must happen, make it user-triggered so it's expected.
3. Web fonts (FOUT)
When your custom font swaps in for the fallback, differing metrics reflow the text. Preload critical fonts and pick a fallback with similar sizing (via size-adjust / font-display) so the swap barely moves anything.
Q1Multiple choice
A dev says 'CLS only counts shifts the user didn't cause, so anything after a click is excused.' Where does that break?
Q2Multiple choice
A reviewer assumes 'CLS just counts how many pixels things move.' What's the actual formula, and why does it matter?
Q3Multiple choice
Every image has width/height, yet CLS still spikes ~300ms after load and the headline visibly reflows. Most likely cause and fix?
Q4Sort each scenario
Does each scenario count against CLS? Two are traps — a shift long after a click, and a move that isn't a layout shift at all.
An ad loads and pushes the article down
Content appears below within 500ms of clicking “Load more”
Text reflows when the web font swaps in
Content jumps a full 2 seconds after you clicked a button
A modal you opened animates in using CSS transform
Key takeaways
→CLS scores unexpected movement of visible content. Good ≤ 0.1.
→Each shift = impact fraction × distance fraction; your score is the worst session window.
→Top cause: images/videos/ads with no reserved dimensions — set width/height or aspect-ratio.
→Reserve space for ads (min-height), overlay cookie banners, and preload fonts.
→User-triggered shifts (within 500 ms of an interaction) are excused.