Cumulative Layout Shift (CLS) measures how much the visible content of a page moves around while it loads. If you've ever been about to tap a button on your phone and had it jump just as you tapped — clicking the wrong thing entirely — you've experienced the problem CLS measures.
Google counts CLS as a Core Web Vital and uses it as a ranking signal. A CLS score above 0.1 is flagged as needing improvement. Above 0.25 is poor.
What Causes Layout Shift?
Layout shift happens when the browser has to recalculate the position of elements because something new appears or changes size after the initial render. The most common causes are:
Images Without Dimensions
When the browser starts rendering your page, it doesn't know how large an image will be until the image has downloaded. Without explicit width and height attributes, the browser allocates no space for the image — then shifts everything down when it arrives.
Fix: Add explicit width and height to every image:``html
`
This is the single most common CLS cause and the easiest fix.
Ads and Embeds Without Reserved Space
Ad networks serve different-sized ads depending on what's available at the time. If no space is reserved for the ad container, everything on the page shifts when the ad loads.
Fix: Set a minimum height on your ad containers in CSS: `css
.ad-container { min-height: 250px; }
`
This prevents content from shifting when the ad loads, even if the actual ad is slightly smaller than the reserved space.
Late-Loading Iframes
Iframes (YouTube videos, embedded maps, social media posts) that load after the main content causes shift if no space is reserved.
Fix: Add aspect ratio placeholders:
`css
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
}
.video-wrapper iframe {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
`
Web Font FOUT (Flash of Unstyled Text)
When custom fonts load, if the fallback font has different dimensions from the web font, text reflowing to the new font dimensions causes layout shift.
Fix: Use font-display: optional for non-critical fonts (prevents swap entirely) or font-display: swap with the CSS size-adjust property to match fallback font dimensions to the web font.
Google Fonts'
display=swap parameter helps, but using system fonts as the primary choice is the cleanest fix for CLS.
Cookie Banners and Popups
Cookie consent banners that push content down rather than overlaying it are a very common CLS source, particularly on the first visit.
Fix: Use position: fixed or position: sticky for cookie banners so they overlay content rather than push it. Set the banner to appear at the bottom of the screen rather than the top.
CSS Animations That Change Layout
CSS animations using properties like
width, height, margin, padding, or top/left/right/bottom trigger layout recalculations and cause shift.
Fix: Animate only transform and opacity, which don't trigger layout. transform: translateY() is the GPU-accelerated alternative to animating top`.
Dynamically Injected Content
If JavaScript inserts new content above existing content after the page has rendered (notification banners, "back to top" buttons appearing, sticky headers), this causes shift.
Fix: Always insert dynamic content below existing content, or reserve space for it from the start.Measuring CLS Accurately
CLS is measured over the entire lifetime of a page visit, not just on load. This means interactions — scrolling, clicking, expanding elements — can all contribute to CLS. Chrome DevTools' Performance panel can show you exactly which elements are causing shift and when.
For field data (real users), check Google Search Console's Core Web Vitals report and PageSpeed Insights' field data section.
Debugging CLS in Chrome DevTools
1. Open DevTools and go to the Performance panel 2. Record a page load 3. Look for purple "Layout Shift" markers in the timeline 4. Click each one to see which elements caused the shift
This is the most reliable way to identify subtle CLS issues that automated scanners miss.