What is CLS? How to fix Cumulative Layout Shift
CLS scores how much a page jumps around while it loads and is used. Google's good mark is 0.1 or less. How the score works, the usual causes and the fixes.
In this guide
What CLS measures
You have seen it. You go to tap a button, the page jumps, and you hit something else. CLS puts a number on how often and how badly that happens. It is one of the three Core Web Vitals, next to LCP for loading and INP for responsiveness.
A layout shift happens when an element that is visible on screen changes its start position between two drawn frames. A new element that appears without pushing anything, or an element that grows without moving its neighbors, is not a shift. Shifts caused by the visitor are excused: if the shift happens within 500 milliseconds of a tap, click or key press, the browser marks it as expected and it does not count. Scrolling, dragging and pinch-zooming do not count as input, so a shift while scrolling is still held against the page.
How a shift is scored
Each shift gets a score equal to two fractions multiplied together:
- The impact fraction is how much of the screen the moving elements involve: the area they covered before the shift combined with the area they cover after it, as a share of the viewport.
- The distance fraction is how far the biggest mover traveled, as a share of the viewport's larger side.
The score of one shift is impact fraction times distance fraction. Take a page where a promotion banner, one fifth of the screen high, appears at the top just after the page has drawn and pushes the content down.
One shift of 0.16 is more than the whole "good" budget. Most pages have several small shifts, and they add up.
Why CLS is the worst burst, not the sum of everything
Shifts are grouped into windows. A new shift joins the current window if it comes less than one second after the previous one and the window is still younger than five seconds. The CLS of a page is the score of its worst window. CLS used to be the sum of every shift in a visit, which punished long sessions on pages that were fine. The window approach judges the worst moment instead.
What counts as good
| CLS | Rating |
|---|---|
| 0.1 or less | Good |
| Over 0.1 and up to 0.25 | Needs improvement |
| Over 0.25 | Poor |
CLS has no unit; it is a score, not a time. Google judges a page at the 75th percentile of real visits, so a page passes when at least three out of four visits are at 0.1 or less. Most pages already do: the 2025 Web Almanac found 81% of mobile pages and 72% of desktop pages with a good CLS. If yours does not, the cause is usually one of the few below.
The usual causes and their fixes
Images and videos without dimensions
When the browser does not know how tall an image will be, it reserves no room, and everything below moves down when the file arrives. Always give img and video elements width and height attributes. Browsers use the two numbers to work out the shape and reserve the right space before the file loads, and CSS can still make the image fluid:
<img src="team.jpg" width="800" height="600" alt="The team at the front desk">img { max-width: 100%; height: auto; }For other boxes, such as an embed or a hero area, use the CSS aspect-ratio property or a min-height. This is the most common cause on the web: in the 2025 Web Almanac, 62% of mobile pages and 65% of desktop pages had at least one image without dimensions.
Ads, embeds and iframes
Reserve the space with a fixed or minimum height. If an ad slot can show different sizes, reserve the most common one, or the smallest, and let the container grow from there. Do not collapse the reserved space when no ad is returned: removing a gap shifts the page just as inserting content does. Content that is added near the top of the screen causes more movement than content at the bottom, because more elements sit below it.
Web fonts
When a web font replaces the fallback font, the text can change size and push everything else around. Set font-display: swap or optional, preload the one or two font files the top of the page needs, and make the fallback font match. The CSS descriptors size-adjust, ascent-override, descent-override and line-gap-override let you tune a fallback font to the metrics of the web font. Chrome's article on font fallbacks walks through it, and fixing layout shift from web fonts shows the arithmetic. size-adjust works in Chrome, Firefox and Safari 17 and later; the three override descriptors work in Chrome and Firefox and are not yet in a released Safari.
Banners and pop-ups at the top
A cookie notice, promotion bar or newsletter box that appears above the content pushes everything down. Reserve the space from the first frame, or show it as an overlay (fixed at the bottom, or over the page) so it moves nothing.
Animations
Animating top, left, width or height moves other elements and counts as layout shift. Animate transform and opacity instead. Moving an element with top and left causes shifts even when the element sits in its own layer.
Content that loads late
Reviews, related products, recommendations and any widget that fills in after the page is drawn leave a gap that is filled later. Reserve the space with a placeholder of about the right size, and when you cannot know the size, put the widget lower on the page where it moves less.
Finding the culprits
- PageSpeed Insights. Lighthouse's "Layout shift culprits" insight lists the worst shifts and names causes it recognizes: an unsized image, a web font, an injected iframe, an animation. A separate audit flags images without explicit width and height.
- Chrome DevTools. In the Performance panel, the Experience track marks each layout shift, and selecting one shows the affected rectangles and the moved elements. The Rendering panel can highlight layout shift regions while you load the page.
Lighthouse names the elements that moved, which are often the ones pushed down rather than the one that pushed them. If a banner is inserted above a paragraph, the paragraph is listed; look above it.
Why lab and field CLS can differ
A lab test mostly sees the page load. Real visitors scroll, hover and wait, so lazy-loaded content, late widgets, shifts inside iframes and animations can add shifts that no lab test ever saw. PageSpeed Insights shows both numbers: the real-user value at the top and the lab value under "Diagnose performance issues". If the two are close, the problem is in the load and the lab can show it. If the field value is much worse, look for shifts after the load: scroll the page slowly and watch.
Pages that the browser can restore from the back/forward cache come back exactly as they were left, with no new shifts. See the back/forward cache guide for how to check yours.
Check your own page
Run the free audit and look at the Cumulative Layout Shift value and the layout shift culprits. Then load the page on a slow connection and watch the first few seconds: whatever jumps is on the list above. If the report flags images without width and height, that is the quickest win.
Sources
- Cumulative Layout Shift (CLS) on web.dev: the definition, the score, session windows and expected shifts.
- Optimize Cumulative Layout Shift on web.dev: the common causes and how to find them.
- Performance chapter of the 2025 Web Almanac: the CLS and image-dimension figures above.
- font-display and size-adjust on MDN.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Core Web Vitals · Book a call