What Is Cumulative Layout Shift?
CLS is the Core Web Vital users notice most viscerally, because it is the one that makes them tap the wrong thing. It is also the cheapest to fix: the causes are a short, well-known list, and the remedies are mostly attributes and CSS rather than architecture.
How is CLS calculated?
Each unexpected shift scores the fraction of the viewport affected multiplied by the distance moved. Scores are grouped into session windows of at most five seconds, and the page’s CLS is the largest window, not the total. This windowing stops long pages accumulating an unfairly high score.
Shifts within 500 milliseconds of a user interaction are excluded, on the reasoning that movement you caused is expected. This is why an accordion expanding on click does not count, while the same content appearing on its own does.
What causes most layout shift?
Images and video without width and height attributes, so the browser cannot reserve space before the file arrives. Ads, iframes and embeds inserted into flowing content. Fonts that swap and re-flow text. Cookie banners and notification bars injected above existing content after render.
The banner case is the one teams argue about, because the banner is usually required and usually added by a third-party script outside the main codebase. Reserving its space in the initial layout, or overlaying rather than inserting it, resolves the shift without removing the banner.
How do you fix it?
Set explicit width and height on every image and video so the browser reserves the aspect ratio. Give ad slots and embeds a fixed minimum height. Preload fonts and use font-display swap with a metrically similar fallback. Overlay late-arriving banners instead of pushing content down.
The width and height attributes are the single highest-yield change. Modern browsers compute an aspect ratio box from them even when CSS resizes the image responsively, so adding them costs nothing in layout flexibility and removes the most common shift entirely.
Why does CLS pass in the lab but fail in the field?
Lab runs load a page once, in a clean state, without cookie consent, personalisation, logged-in content or slow third-party scripts arriving late. Real sessions include all of those, and shifts triggered by them appear only in field data collected from actual visits.
Lazy-loaded content that shifts as the user scrolls is another field-only failure, since a lab run does not scroll. If field CLS fails while lab CLS passes, look at what happens after the initial viewport and at what third parties inject.
Key takeaways
- CLS scores unexpected movement as viewport fraction multiplied by distance moved.
- The reported value is the worst five-second session window, not the page total.
- Shifts within 500 milliseconds of an interaction are excluded as expected movement.
- Width and height attributes on images remove the single most common cause.
- Field CLS can fail while lab passes, because consent banners and scrolling only occur in real sessions.
Frequently asked questions
- Does CSS aspect-ratio replace width and height attributes?
- It solves the same problem and is useful for responsive containers, but the HTML attributes still help because they apply before any stylesheet loads. Using both is the safer pattern: attributes give the browser dimensions immediately, and CSS controls how the image scales.
- Do animations count as layout shift?
- Transforms do not, because they do not affect layout of surrounding content. Animating properties such as top, left, width or height does cause shift and will be measured. This is a strong reason to animate with transform and opacity rather than layout-affecting properties.
- How do you handle cookie banners without shifting?
- Render the banner as a fixed overlay above the page rather than inserting it into the document flow, or reserve its height in the initial layout so nothing moves when it appears. Both keep the banner fully functional while removing the shift it would otherwise cause.
- Is a small amount of shift acceptable?
- Yes. The threshold is 0.1 rather than zero, which allows for minor movement. Chasing a perfect zero is rarely worth the constraints it imposes on dynamic content. Stay comfortably under the threshold rather than eliminating every possible shift.
Web Performance, BigBalli. We track Core Web Vitals definitions and thresholds as Google revises them, cross-checked against web.dev and Chrome developer documentation.