Reducing CLS requires identifying the specific elements that are shifting and then addressing the root cause of each one. This guide covers every common source of layout shift with specific, implementable solutions.
Before attempting any fixes, you need to identify precisely which elements are causing layout shifts on your pages. Fixing CLS without measurement is guesswork. The most efficient approach is to use Google PageSpeed Insights to identify the shifting elements, then use Chrome DevTools to observe the shifts in real time and confirm which resource or script is responsible.
Once you have identified the shifting elements, the remediation approach depends on the cause. The sections below cover every major category in order of how commonly each one appears in practice.
The single most common cause of layout shift is images and video elements without explicit width and height attributes. When the browser encounters an image tag with no declared dimensions, it has no information about how much space to reserve for the image before the file downloads. The browser renders surrounding content as if the image does not exist, and then when the image arrives and the browser measures it, the layout shifts to accommodate it.
The fix is to add width and height attributes to every <img> and <iframe> element, using the image's natural pixel dimensions:
Modern browsers use these attributes to calculate the image's aspect ratio and reserve the correct amount of space even before the image file begins downloading. For responsive images, you also need to set aspect-ratio in CSS so the reserved space scales correctly with the container width:
In practice, browsers that support the aspect-ratio property (all modern browsers) will automatically derive the correct aspect ratio from the declared width and height HTML attributes. You do not need to write aspect-ratio explicitly in CSS as long as you have declared both dimensions in HTML.
If your images are managed through WordPress, Shopify, or another CMS, check whether the platform automatically outputs width and height attributes. WordPress has done this since version 5.5. If your theme or a custom template is stripping these attributes, that is where the fix needs to happen — in the template output, not the media library.
Ad slots that load content of variable dimensions are a persistent source of layout shift on publisher and e-commerce sites. The ad network delivers creative of whatever size it has available, and without a pre-allocated container, that creative pushes existing content out of position upon arrival.
The standard solution is to apply a min-height to every ad container before the ad loads. Use the minimum size you would accept for that slot based on your ad unit configuration:
For Google AdSense, enable the Auto ads feature with anchor or vignette ad formats, which are designed to overlay content rather than displace it. For Display ads placed in-content, always configure a fixed-size ad unit with a min-height on the container that matches the smallest creative that unit will serve.
Cookie consent banners and GDPR notices that inject themselves above existing content at page load are a frequent source of shift on European and global sites. The cleanest solution is to use position: fixed or position: sticky for the banner so it overlays the page without displacing other elements:
If the banner must appear at the top of the page and push content down, reserve space for it in the initial HTML response so that when the JavaScript fires and populates the banner, no shift occurs because the space was already allocated.
Web fonts cause layout shift through a mechanism known as flash of unstyled text (FOUT): the browser renders text in a fallback system font initially and then swaps to the web font once it downloads. If the two fonts have different metrics — different character widths, line heights, or ascent values — the text block reflowing after the font swap shifts surrounding elements.
There are two complementary approaches to eliminating font-related CLS.
The optional value instructs the browser to use the web font only if it is already cached; otherwise, it uses the fallback font for this page load. This completely eliminates font-swap CLS but means the web font may not appear on the first visit:
If you require the web font to appear on every visit, use font-display: swap combined with size-adjust, ascent-override, and descent-override to match the fallback font's metrics as closely as possible to the web font. This minimizes visible reflow when the swap occurs:
Preloading the font file ensures it is available sooner, reducing the window during which the fallback font is displayed:
Any content inserted into the document flow above already-rendered content after the initial page load will cause a layout shift. This includes dynamically loaded modules, sticky header changes, personalization blocks, and chat widget launchers. The shift impact is proportional to how close to the top of the viewport the insertion point is and how tall the inserted content is.
The best approaches, in order of preference, are:
Animations that modify layout-affecting properties — top, left, bottom, right, margin, padding, width, or height — force the browser to recalculate the layout of affected elements and their neighbors on every animation frame. This can contribute to CLS if other elements shift in response.
The solution is to use transform-based animations instead. transform: translate(), transform: scale(), and opacity are all composited on the GPU and do not affect the document layout:
Image sliders and carousels frequently cause CLS when the component reserves space for only one slide height and then expands or contracts as slides of different heights load. The fix is to set a fixed height on the carousel container that accommodates the tallest slide, or to use an aspect-ratio-based approach that reserves space before any slide images load:
Many third-party scripts — analytics libraries, tag managers, chat widgets, survey tools — inject elements into the DOM after load, often without pre-allocating space. For scripts that are not critical to the initial render, use defer or async attributes to prevent them from blocking parsing, and consider loading them only after the page's main content has rendered:
For tag manager-deployed scripts, use consent mode or trigger rules to delay firing tags until after the page is interactive, rather than firing them on DOM Ready when layout shifts have the most visible impact.
After implementing changes, always verify the impact before considering the work complete. The recommended verification workflow is:
Run our free CLS checker to see your score, identify which elements are shifting, and get a diagnosis of the most likely cause for each one — so you know exactly what to fix.
Test My CLS Score