Cumulative Layout Shift (CLS)

CLS measures how much the page jumps around, like the button that moves just as you tap it. It is the Core Web Vital for visual stability.

Thresholds measured at the 75th percentile of page loads, per Google’s web.dev guidance.

How a layout shift is scored

Each unexpected shift gets a score of impact fraction × distance fraction. The impact fraction is how much of the viewport the moving content covers, before and after the move combined. The distance fraction is how far it moved, relative to the viewport. Shifts that happen close together (less than 1 s apart, within a 5 s window) are added into one “session window”, and CLS is the worst window.

Late-loading banner calculator

impact 0.533 × distance 0.107 = 0.057 per shift

CLS 0.06 → Good

Viewport: 390 × 844 phone. Impact fraction = share of the viewport touched by the moving content before and after the move; distance fraction = how far it moved relative to the viewport height.

Common causes and fixes

CauseFix
Images and videos without dimensionsAdd width and height attributes, or CSS aspect-ratio
Ads, embeds and iframesReserve the slot with min-height at its most likely size
Cookie banners and promo bars inserted at the topOverlay them (position fixed) instead of pushing content down
Web fonts swapping in with different metricsTune the fallback with size-adjust / ascent-override, or preload the font
Content injected after an API callRender a skeleton of the same size first
Animating top, height or marginAnimate transform instead, which never causes layout shifts

Questions people ask

What is Cumulative Layout Shift?

CLS measures unexpected movement of visible content while a page is open. Each shift is scored as impact fraction × distance fraction, shifts within a short burst are added up, and CLS is the largest burst (session window) in the visit.

What is a good CLS score?

0.1 or less at the 75th percentile. 0.1–0.25 needs improvement; above 0.25 is poor. CLS has no unit.

Do all layout shifts count?

No. Shifts within 500 ms after a click, tap or key press are excluded, because the user expects the page to change. Animations that use CSS transform also don’t count.

Why is my field CLS higher than Lighthouse CLS?

Lighthouse only watches the initial load. Real visitors scroll, which triggers lazy-loaded images, ads and embeds, and shifts from those only show up in field data.