Skip to content

Preventing Layout Shifts

Preventing Layout Shifts

Cumulative Layout Shift (CLS) occurs when elements on a page move unexpectedly as content loads, disrupting user experience. Preventing layout shifts requires proactive design choices to reserve space for dynamic content, use CSS placeholders, and manage font loading. Below are key strategies to mitigate CLS.


1. Reserve Space for Dynamic Content

Dynamic content (e.g., images, iframes, or third-party widgets) can cause layout shifts if their dimensions are not known upfront. Reserve space using explicit width and height attributes or CSS properties to prevent unexpected reflows.

Example: Image Resizing

<!-- Reserve space for an image -->
<img src="example.jpg" width="300" height="200" loading="lazy" alt="Example">

Example: CSS Placeholder with Aspect Ratio

/* Use aspect-ratio to reserve space for a video */
.video-placeholder {
  aspect-ratio: 16 / 9;
  background-color: #ccc;
}

Command: Use browser devtools to inspect layout shifts and verify reserved space.


2. Use CSS Placeholders for Loading States

When content is loaded asynchronously (e.g., via JavaScript), use CSS to create placeholders that match the final layout. This prevents shifting as the content appears.

Example: Loading Spinner with Placeholder

<div class="card-placeholder" aria-label="Loading...">
  <div class="spinner"></div>
</div>

<style>
.card-placeholder {
  width: 300px;
  height: 200px;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
}

.spinner {
  width: 100%;
  height: 100%;
  /* Spinner animation here */
}
</style>

Command: Use aspect-ratio or padding-top for responsive placeholders (e.g., for ads or iframes).


3. Manage Font Loading to Avoid Shifts

Fonts can cause layout shifts if they load after the page has rendered. Use font-display: swap to show a fallback font immediately and swap it in when the custom font is ready.

Example: Font Loading with font-display: swap

@import url('https://example.com/roboto.woff2') format('woff2');
body {
  font-family: 'Roboto', sans-serif;
  font-display: swap;
}

Command: Preload critical fonts using <link rel="preload">:

<link rel="preload" href="https://example.com/roboto.woff2" as="font" type="font/woff2">


4. Avoid Layout Shifts from Third-Party Content

Third-party scripts (e.g., ads, analytics) often load asynchronously and can shift content. Reserve space for these elements using aspect-ratio or height attributes.

Example: Reserving Space for an Ad

<div class="ad-placeholder" style="aspect-ratio: 3 / 2;"></div>

Command: Lazy-load non-critical third-party content using loading="lazy" or defer scripts.


Key takeaways

  • Reserve space for dynamic content using width, height, or aspect-ratio to prevent reflows.
  • Use CSS placeholders (e.g., background-color, padding) to maintain layout stability during loading.
  • Manage font loading with font-display: swap and preload to avoid layout shifts.
  • Reserve space for third-party content to ensure predictable layout behavior.