Cumulative Layout Shift breaks WordPress sites more often than any other Core Web Vital because the platform's open architecture invites layout-shifting injections from themes, plugins, ad networks, cookie banners and lazy-loading optimisers. This guide walks the WordPress-specific audit-and-fix loop: identify the source, apply the fix where it lives (theme, plugin, custom code), and verify against the CLS Debugger output. Related fixes: LCP and INP on the same site usually move together with CLS.
Open PageSpeed Insights at https://pagespeed.web.dev/ and run five representative URLs from your WordPress site: homepage, top-traffic blog post, a category archive page, a contact or about page, and (if applicable) a WooCommerce product page. Note the CLS score under mobile — that's where most WordPress sites fail. A score above 0.25 is poor; under 0.1 is good. Most WordPress sites running default themes with plugins score 0.15–0.40 untreated.
Pair this with our CLS Debugger which records the actual shifting elements in the DOM so you can identify the source rather than guess. The Debugger flags the highest-impact shift first — fixing it usually halves your CLS in one change.
Since WordPress 5.5, the core Image block automatically adds width and height attributes to img tags from the media library. But three common WordPress patterns skip this:
Theme template images. Hero banners, featured-image fallbacks, and theme-default placeholders often output <img src="..."> without dimensions. Audit your theme's template files (header.php, single.php, archive.php) and add explicit attributes:
<img src="<?php echo get_template_directory_uri(); ?>/img/hero.jpg"
width="1200" height="600" alt="..." />
ACF (Advanced Custom Fields) images. When outputting an ACF image field manually, dimensions are often omitted. Use the array return type and output explicitly:
<?php $img = get_field('hero_image'); ?>
<img src="<?php echo esc_url($img['url']); ?>"
width="<?php echo $img['width']; ?>"
height="<?php echo $img['height']; ?>"
alt="<?php echo esc_attr($img['alt']); ?>" />
Page builder content. Elementor, Divi and Beaver Builder sometimes inject inline images without dimensions, particularly in older templates or custom widget configurations. Run a site-wide HTML scan with our HTML Checker to find images missing dimensions, then edit the builder modules.
Late-loading ads are the single biggest CLS culprit on content WordPress sites. The fix is to reserve the exact slot dimensions before the ad request fires:
<div class="ad-slot" style="min-height:250px;display:block"> <!-- AdSense / Ezoic / MediaVine code here --> </div>
For AdSense Auto-ads (which inject ads dynamically without your control), the most reliable mitigation is to switch off Auto-ads and place manual ad units with reserved containers. AdSense Auto-ads on WordPress score CLS poorly almost unavoidably.
For Ezoic and MediaVine, both publishers provide WordPress plugins. Enable the plugin's "preserve slot dimensions" or "CLS-safe mode" option (named differently in each). MediaVine specifically has the Trellis theme which is CLS-optimised; if you're on MediaVine and CLS-burdened, switching themes is the fastest path.
Font-swap CLS happens when a fallback font renders first, then swaps to your web font once it loads, shifting all surrounding text. Three fixes, in order of effectiveness:
1. Use font-display: optional in your @font-face declarations. This tells the browser to use the fallback for 100ms only — if the web font isn't ready, it sticks with the fallback for the whole session. Zero CLS, slight visual inconsistency on slow networks.
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: optional;
}
2. Host Google Fonts locally. Loading from fonts.googleapis.com adds DNS, TLS and CSS request overhead. Use a plugin like OMGF (Optimize My Google Fonts) or download and self-host. Combine with font-display: optional for maximum effect.
3. Match the fallback font metrics. Use size-adjust, ascent-override and descent-override in @font-face so the fallback renders at the same height as your web font:
@font-face {
font-family: 'Inter-fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
}
This is the most painful step because the culprit is usually a plugin you "need." The systematic approach:
On a staging copy of your site, disable plugins one by one and re-measure CLS after each. Plugins that commonly cause CLS in WordPress:
position: sticky, not JS-toggled.After each batch of fixes, re-run PageSpeed Insights. Lab data updates immediately. Field data (the 28-day rolling CrUX dataset that Google actually uses for Core Web Vitals ranking signals) takes 4-6 weeks to fully reflect changes. Track both: lab numbers daily during the fix programme, then watch field data trend over the following month.
Verify with a real Chrome DevTools Performance recording on a throttled "Fast 3G" connection — that's closer to real mobile conditions than the default desktop. Look for shifts in the Layout Shift Regions visualisation.
Identify the exact elements causing layout shift with our CLS Debugger.
Run CLS Debugger →