Cumulative Layout Shift above 0.1 — Google's 'needs improvement' threshold under ISO-25010 time-behaviour — causes visible content jumps that erode user trust and trigger accidental clicks. A hero image without explicit dimensions reserves no space in the layout; when it loads, everything below it shifts down. A cookie consent bar using position: relative shoves the page body down every time it appears. Beyond user frustration, high CLS is a Core Web Vitals failure that degrades page experience scores in Google Search and can reduce organic rankings for the affected URL. Marketing pages built with AI tools are especially prone to this — image dimensions are frequently omitted and cookie banners are injected as afterthoughts.
Critical because visible layout shifts destroy user trust and directly lower Google Core Web Vitals scores, reducing organic search rankings for the affected marketing page.
Fix each CLS source independently — every <img> tag needs explicit dimensions, every font needs font-display: swap, and every notification bar needs fixed positioning so it overlays rather than shifts content.
// 1. Dimensions on every image
<img src="/feature.webp" width={600} height={400} alt="Feature" />
// 2. Font loading in globals.css
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap; /* show fallback immediately, swap when loaded */
}
// 3. Cookie banner — fixed so it never shifts body content
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 50;
}
For Next.js, use next/font instead of @font-face — it handles font-display: swap and self-hosting automatically.
ID: marketing-page-speed.core-web-vitals.cls-threshold
Severity: critical
What to look for: Cumulative Layout Shift happens when elements move after the page initially renders — most commonly from: (1) images without explicit width/height attributes, (2) fonts causing text reflow (FOIT/FOUT without font-display), (3) dynamically injected banners, cookie consent bars, or ad slots that push content down, (4) late-loading embeds (videos, iframes) without reserved space. Examine image tags, font declarations, and any banner/notification components. Count all instances found and enumerate each.
Pass criteria: All images have explicit width and height attributes (or use Next.js Image which requires them). Fonts use font-display: swap or optional. Cookie consent banners and notification bars are positioned to not shift existing content (fixed/absolute positioning). No ad slots or iframes inject without reserved space. Threshold: under 0.1 Cumulative Layout Shift score.
Fail criteria: Images lack width/height attributes throughout the marketing pages. Fonts use default font-display: auto (blocks rendering). Cookie consent bar slides in and pushes content down. Any of these reliably produce CLS > 0.1. Do NOT pass if images or iframes lack explicit width and height attributes — these cause layout shifts even if CLS happens to measure below 0.1 on a single test.
Skip (N/A) when: Project has no marketing pages with images or dynamic content.
Cross-reference: The font-loading-strategy check verifies font-display settings that directly affect CLS when web fonts load.
Detail on fail: "Images in HeroSection.tsx and FeatureGrid.tsx lack width/height. Font in globals.css uses font-display:auto. Cookie banner in CookieBanner.tsx uses position:relative — all three contribute to high CLS."
Remediation: Attack each CLS source:
// 1. Images — always specify dimensions
<img src="/feature.webp" width={600} height={400} alt="Feature" />
// or Next.js Image (dimensions required)
<Image src="/feature.webp" width={600} height={400} alt="Feature" />
// 2. Fonts — swap immediately
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap;
}
// 3. Cookie banner — position fixed to avoid shifting content
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 50;
/* does NOT push body content down */
}