SEO

CLS Guide: How to Optimize Cumulative Layout Shift

By SelestL • Published on
CLS Guide: How to Optimize Cumulative Layout Shift

There are few web browsing experiences more frustrating than attempting to tap an article link or checkout button, only for a sudden visual shift to push the target downward at the last millisecond, causing you to click an advertisement or trigger the wrong action. This visual instability not only ruins user trust and conversion rates, but it also directly depresses organic search visibility. Google created Cumulative Layout Shift (CLS) as a Core Web Vital specifically to quantify and penalize unexpected layout jumps.

Unlike metrics that measure network speed or asset loading timelines, CLS evaluates visual stability throughout the entire lifecycle of a page visit. A page can achieve instantaneous server response times and rapid paint milestones, but if elements unexpectedly shift position while reading or interacting, the page will fail Google's Core Web Vitals assessment. Achieving consistent visual stability requires disciplined CSS architecture and precise DOM rendering controls.

In this technical guide, we will analyze the mathematical mechanics of layout instability, examine official standards from web.dev CLS metric documentation, review the W3C Layout Instability API specification, and implement advanced engineering solutions from web.dev's Optimize CLS technical guide.


How Cumulative Layout Shift (CLS) Is Calculated

How Cumulative Layout Shift (CLS) Is Calculated

A layout shift occurs whenever a visible DOM element changes its start position between two rendered frames without an associated user interaction. The browser calculates the shift score using two key geometric factors:

The CLS Formula:

Layout Shift Score = Impact Fraction * Distance Fraction

  • Impact Fraction: Measures how much viewport area the unstable element occupies across both frames. If an element covering 50% of the viewport shifts downward by 20%, the combined impacted area is 70% of the viewport (Impact Fraction = 0.70).
  • Distance Fraction: Measures the greatest distance the unstable element moved relative to the viewport dimension. If an element moved downward by 20% of the viewport height, the Distance Fraction is 0.20.
  • Shift Calculation: In this scenario, the layout shift score is 0.70 * 0.20 = 0.14.

Google Core Web Vitals Thresholds for CLS

  • Good (Passing): 0.10 or less.
  • Needs Improvement: Between 0.10 and 0.25.
  • Poor (Failing): Greater than 0.25.

Google measures CLS using Session Windows. A session window groups consecutive layout shifts that occur with less than 1 second between shifts, capped at a maximum window duration of 5 seconds. Google records the single highest session window score observed across a user's visit, evaluated at the 75th percentile in the Chrome User Experience Report (CrUX).


The 4 Primary Causes of High CLS Scores

Nearly all unexpected layout shifts can be traced to four specific frontend architectural patterns:

Cause Mechanism Impact Level
1. Unsized Media Elements Images, videos, or iframes loaded without explicit width/height or CSS aspect-ratio. Severe (Shifts entire page)
2. Dynamically Injected Content Display ads, newsletter banners, or cookie notices injected above existing content without reserved space. Severe (Shifts text downward)
3. Web Font Metric Mismatch Custom web fonts swapping in for fallback fonts with different glyph sizes, causing text reflow (FOUT). Moderate (Line-wrap jumps)
4. Non-Composited Animations Animating CSS geometry properties (top, left, height, margin) instead of GPU-composited transforms. Continuous micro-shifts

Engineering Solutions for Zero-Shift Layouts

1. Reserving Aspect Ratio on Images and Videos

Historically, responsive web design encouraged setting width: 100%; height: auto; in CSS. Before the image file finishes downloading, the browser has zero knowledge of the image dimensions, collapsing its height to 0 pixels. When the image finally arrives, the browser abruptly expands the element, pushing all subsequent content downward.

The modern standard combines HTML dimension attributes with the MDN Web Docs aspect-ratio CSS property. Modern browsers automatically compute the aspect ratio from the HTML width and height attributes, pre-allocating the correct vertical space before the image binary downloads:

<!-- Pre-allocating container space via HTML attributes -->
<img 
  src="/images/architecture-diagram.webp" 
  alt="Technical SEO Infrastructure Diagram"
  width="1200" 
  height="675" 
  class="w-full h-auto block"
  fetchpriority="high"
/>

<!-- Responsive CSS Container with Explicit aspect-ratio -->
<style>
  .media-wrapper {
    aspect-ratio: 16 / 9;
    width: 100%;
    background-color: #f3f4f6; /* Subtle placeholder background */
  }
</style>

For more image performance strategies, review our Image Optimization Guide and our LCP Optimization Guide.

2. Reserving Ad and Banner Slots with min-height

Dynamic display advertisements (like Google AdSense or programmatic header bidding) and consent notices are major contributors to CLS because ad creatives load asynchronously after the main DOM has painted. If an ad container begins with zero height and expands to 250px after an auction concludes, the entire article shifts.

Always pre-allocate slot dimensions in CSS:

<!-- Reserving slot dimensions for programmatic ad slots -->
<div class="ad-slot-container" style="min-height: 250px; min-width: 300px; display: flex; justify-content: center; align-items: center;">
  <!-- Dynamic Ad Injected Here -->
</div>

3. Eliminating Font Reflow with Font Metric Overrides

When custom web fonts load using font-display: swap, the browser renders an initial system fallback font (such as Arial or Georgia). When the custom web font arrives, it swaps in. If the character width, line height, or ascent metrics differ between the two fonts, paragraphs re-wrap onto new lines, causing layout shifts.

Modern CSS eliminates this issue using font metric descriptors defined in the MDN Web Docs @font-face size-adjust reference. By adjusting the fallback font's bounding box, the fallback font matches the web font's exact geometry:

/* Standard Custom Web Font */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap;
}

/* Matched Fallback Font */
@font-face {
  font-family: 'Inter-Fallback';
  src: local('Arial');
  ascent-override: 90%;
  descent-override: 22.5%;
  line-gap-override: 0%;
  size-adjust: 107.5%;
}

body {
  font-family: 'Inter', 'Inter-Fallback', sans-serif;
}

4. Animating Exclusively via CSS Transforms

Never animate layout-inducing CSS properties like top, left, height, width, or margin in dropdown menus, mobile navigation drawers, or tooltips. Animating geometry properties forces the CPU to recalculate layout geometry on every single frame, generating continuous layout shifts.

Instead, animate exclusively with GPU-composited properties: transform: translate3d(), transform: scale(), and opacity. Composited properties execute directly on the GPU compositor thread without triggering layout reflows or impacting CLS scores.


Measuring Layout Shifts with JavaScript Attribution

To detect exactly which DOM elements are shifting on your production site, observe layout instability events via the PerformanceObserver API:

<script type="module">
  import { onCLS } from 'https://unpkg.com/web-vitals@4?module';

  onCLS((metric) => {
    if (metric.value > 0.1) {
      console.warn('CLS Threshold Exceeded:', {
        value: metric.value,
        rating: metric.rating,
        entries: metric.entries.map((entry) => ({
          value: entry.value,
          sources: entry.sources.map((source) => ({
            node: source.node,
            currentRect: source.currentRect,
            previousRect: source.previousRect,
          })),
        })),
      });
    }
  });
</script>

Strategic Checklist for Perfect CLS Performance

  • Declare Explicit Dimensions: Provide width and height attributes on all <img>, <video>, and <iframe> tags.
  • Pre-Allocate Dynamic Containers: Use CSS min-height or aspect-ratio on ad slots, embeds, and alert banners.
  • Match Font Metrics: Use CSS size-adjust and metric overrides on fallback fonts to eliminate text reflow jumps.
  • Keep User Inputs Under 500ms: Shifts occurring within 500ms of user taps are exempt; ensure interactions respond within this window by following our INP Optimization Guide.
  • Avoid Top-Injected Banners: Overlay modal banners or reserve space rather than pushing content down.
  • Conduct Regular Technical Audits: Keep your entire technical foundation optimized using our Technical SEO Audit Framework and review our Next.js SEO Architecture Guide.

Need dedicated performance engineering to resolve Core Web Vitals issues, refactor frontend stability, or build ultra-fast web architectures? Learn more about our custom engineering services or reach out to our senior technical team via our consultation portal.

Related Articles