How to Reserve Space to Prevent Layout Shift | SpeedVitals Blog

If you found this article, you probably saw a warning about layout shift, CLS, or "Avoid large layout shifts" while testing your website.

In simple terms, some element on your web page has moved after the page has already started loading. It could be an image, ad, iframe, font, or any content loaded by JavaScript.

This is not just a small visual issue. When content moves unexpectedly, users lose their reading position, click the wrong element, or feel that the page is unstable.

The fix is usually to reserve the right amount of space before the element loads. When the browser already knows how much space an image, ad, embed, font, or dynamic component will need, it can build a stable layout from the beginning.

In this guide, you will learn what layout shift is, why it affects Cumulative Layout Shift (CLS), and how to reserve space for images, ads, embeds, fonts, skeletons, dynamic content, and WordPress websites.

What Is Layout Shift?

A layout shift happens when a visible element changes its position from one rendered frame to the next.

For example:

The important point is this: layout shift is not just about something being added to the page. It becomes a problem when that addition or resize causes existing visible content to move unexpectedly.

This is why layout shift usually happens during:

A stable page tells the browser the expected size of important elements before the resources are fully available.

Why Reserving Space Prevents Layout Shift

Browsers create layout before every asset has finished loading.

If an image, iframe, ad, or component has no known dimensions, the browser may initially allocate little or no space for it. Later, when the resource loads and the actual height becomes available, the browser has to recalculate the page layout.

That recalculation pushes nearby content.

Reserving space solves this by giving the browser enough layout information upfront.

Instead of this:

<img src="/hero.jpg" alt="Hero image">

Use this:

<img
  src="/hero.jpg"
  width="1200"
  height="675"
  alt="Hero image"
>

The browser can now calculate the aspect ratio immediately and reserve the correct height even before the image file has downloaded.

This is one of the simplest and most effective ways to prevent CLS.

How Layout Shift Affects Core Web Vitals

Cumulative Layout Shift measures visual stability. A lower CLS means users are less likely to experience unexpected movement.

For a good user experience, Google recommends a CLS score of 0.1 or less at the 75th percentile of page loads across mobile and desktop. A score above 0.25 is considered poor.

CLS Score Rating Meaning
0.1 or less Good The page is visually stable for most users
0.1 to 0.25 Needs Improvement Some users may experience noticeable movement
Above 0.25 Poor Layout instability is likely hurting user experience

CLS is especially important because layout shifts are not just visual issues. They can cause real usability problems.

A user may:

Layout stability also affects how users perceive LCP. Even if your Largest Contentful Paint element appears quickly, the page can still feel poor if the surrounding layout keeps moving. If your main issue is that the hero image itself is discovered too late, you should also check how to preload the LCP image.

A fast page that jumps around does not feel fast.

Common Causes of Layout Shift

Most CLS issues come from elements that load late without reserved dimensions.

Cause Why It Shifts Typical Fix
Images without dimensions Browser does not know the final image height Add width and height attributes
Responsive images with inconsistent ratios Different image candidates have different shapes Keep the same aspect ratio or define ratios per breakpoint
Ads Ad slot loads after page layout is created Reserve a fixed or minimum ad container height
Embeds and iframes Third-party content resizes after loading Wrap in an aspect-ratio container
Lazy-loaded content Content appears after scroll without space Use placeholders, skeletons, or min-height
Fonts Web font metrics differ from fallback font Use better fallbacks, preload fonts, and metric overrides
Dynamic components JavaScript inserts content above existing content Reserve a container or insert after user interaction
Sticky bars and banners Page content is pushed after banner appears Reserve header/banner space or overlay it

The fix is usually not complicated. The difficult part is identifying which element caused the movement.

How to Reserve Space for Images

Images are one of the most common causes of layout shift.

The best practice is to always include width and height attributes on image elements. These attributes do not force the image to render at that exact pixel size when responsive CSS is used. Instead, modern browsers use them to calculate the image's aspect ratio.

Good Image Markup

<img
  src="/images/product.jpg"
  width="800"
  height="600"
  alt="Product preview"
>

Then make it responsive with CSS:

img {
  max-width: 100%;
  height: auto;
}

This combination gives the browser the intrinsic aspect ratio while still allowing the image to scale with the layout.

Bad Image Markup

<img src="/images/product.jpg" alt="Product preview">

Without dimensions, the browser may not know how much vertical space to reserve until the image starts downloading.

Responsive Images With Srcset

Responsive images should still include dimensions.

<img
  src="/images/product-800.jpg"
  srcset="
    /images/product-400.jpg 400w,
    /images/product-800.jpg 800w,
    /images/product-1200.jpg 1200w
  "
  sizes="(max-width: 768px) 100vw, 768px"
  width="800"
  height="600"
  alt="Product preview"
>

The important rule is that the image candidates in srcset should use the same aspect ratio.

If one image is 4:3 and another is 16:9, the browser may reserve one ratio and later render another, causing movement.

Picture Elements and Art Direction

Sometimes mobile and desktop intentionally use different crops. In that case, define dimensions on the source elements where supported and ensure the fallback img also has dimensions.

<picture>
  <source
    media="(max-width: 767px)"
    srcset="/images/hero-mobile.jpg"
    width="600"
    height="750"
  >
  <source
    media="(min-width: 768px)"
    srcset="/images/hero-desktop.jpg"
    width="1440"
    height="600"
  >
  <img
    src="/images/hero-desktop.jpg"
    width="1440"
    height="600"
    alt="Dashboard preview"
  >
</picture>

For art-directed images, test both desktop and mobile. CLS problems often appear only on one viewport because the crop, container width, or text wrapping changes.

CSS Aspect Ratio for Image Containers

If you do not control the image markup directly, reserve space on the wrapper.

<div class="image-frame">
  <img src="/images/article-cover.jpg" alt="Article cover">
</div>
.image-frame {
  aspect-ratio: 16 / 9;
  width: 100%;
  overflow: hidden;
}

.image-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

This is useful for CMS content, card grids, thumbnails, and user-generated images.

How to Reserve Space for Ads and Embeds

Ads and embeds are harder than images because their final size may depend on a third-party script.

Still, you should never allow an ad or embed container to start at 0px height if it will later appear inside the content flow.

Reserve Space for Ad Slots

<div class="ad-slot ad-slot-sidebar">
  <!-- Ad script renders here -->
</div>
.ad-slot {
  display: block;
  width: 100%;
  min-height: 250px;
  background: #f5f5f5;
}

.ad-slot-sidebar {
  min-height: 280px;
}

@media (max-width: 767px) {
  .ad-slot {
    min-height: 320px;
  }
}

The correct height depends on your ad inventory. Use historical ad sizes, common slot dimensions, and device-specific behavior to choose a realistic value.

If the ad does not load, avoid collapsing the container immediately. Removing reserved space can cause the same CLS problem as inserting the ad late.

Reserve Space for YouTube, Maps, and Iframes

Embeds should usually be wrapped in an aspect-ratio container.

<div class="embed-frame">
  <iframe
    src="https://www.youtube.com/embed/video-id"
    title="Video"
    loading="lazy"
    allowfullscreen
  ></iframe>
</div>
.embed-frame {
  aspect-ratio: 16 / 9;
  width: 100%;
}

.embed-frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

This prevents the iframe from appearing as a small or zero-height element before expanding.

Ads Above the Fold

Be especially careful with ads near the top of the page.

A late-loading ad above the article title, product grid, or main content can create a large CLS score because it moves a large part of the viewport.

For above-the-fold ads:

How to Reserve Space for Dynamic Content

Dynamic content is content added after the initial HTML is rendered. This includes recommendations, reviews, related posts, product cards, filters, personalization blocks, and JavaScript-rendered UI.

If this content appears in the normal document flow, reserve its space.

Use Min-Height for Dynamic Sections

<section class="related-products">
  <h2>Related Products</h2>
  <div id="related-products-list"></div>
</section>
.related-products {
  min-height: 420px;
}

This gives the browser enough space before the JavaScript finishes loading.

Use Skeletons for Predictable Components

Skeletons work well when the final layout is known.

<div class="product-card product-card-skeleton">
  <div class="product-card-image"></div>
  <div class="product-card-title"></div>
  <div class="product-card-price"></div>
</div>
.product-card {
  display: grid;
  gap: 12px;
}

.product-card-image {
  aspect-ratio: 4 / 3;
  background: #eee;
}

.product-card-title {
  height: 20px;
  width: 80%;
  background: #eee;
}

.product-card-price {
  height: 18px;
  width: 40%;
  background: #eee;
}

The skeleton should match the final component dimensions closely. A skeleton that is much shorter than the final content still causes layout shift.

Avoid Inserting Content Above Existing Content

This is a common issue with:

Bad approach:

document.body.prepend(promoBanner);

This pushes the whole page down after the user has already started viewing it.

Better approaches:

Infinite Scroll and Load More

Infinite scroll can create post-load layout shifts if new items are inserted above or inside the visible viewport.

For stable loading:

Layout shifts shortly after direct user input may be treated differently by CLS measurement, but the user experience still matters. Do not rely on the metric exception as a design strategy.

If JavaScript-heavy widgets are also delaying rendering or blocking interaction, fixing layout stability should be combined with delaying JavaScript safely.

How to Reserve Space for Fonts and Text

Fonts can also cause layout shift.

When a web font loads, it may replace the fallback font. If the fallback font has different metrics, text can become wider, narrower, taller, or shorter. That can move surrounding content.

Use a Similar Fallback Font

Bad:

body {
  font-family: "Inter";
}

Better:

body {
  font-family: "Inter", Arial, sans-serif;
}

Always define a fallback font that is visually and metrically close to the web font.

Preload Critical Fonts

If a font is required for above-the-fold text, preload it.

<link
  rel="preload"
  href="/fonts/inter-var.woff2"
  as="font"
  type="font/woff2"
  crossorigin
>

Preloading helps the browser discover the font earlier, reducing the chance of late font swaps.

Only preload critical fonts. Preloading too many font files can delay other important resources, including the LCP image.

Use Font Display Carefully

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-var.woff2") format("woff2");
  font-display: swap;
}

font-display: swap keeps text visible using a fallback font, then swaps to the web font when it loads. This is usually better than invisible text, but it can still cause layout shift if the metrics differ.

For some websites, font-display: optional may reduce re-layout because the browser can keep the fallback font if the web font is not available early enough.

Use Font Metric Overrides

Modern CSS allows you to tune fallback font metrics with properties such as:

Example:

@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

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

This can reduce text reflow when the real font replaces the fallback. The exact values should be calculated based on your font pair instead of guessed.

Modern CSS Techniques for Preventing Layout Shift

Modern CSS gives us several tools to make layouts more predictable.

Aspect Ratio

aspect-ratio is one of the most useful CSS properties for layout stability.

.hero-media {
  aspect-ratio: 16 / 9;
}

Use it for:

Min-Height

Use min-height when content height is variable but should never start from zero.

.testimonial-widget {
  min-height: 260px;
}

This is useful for:

CSS Grid and Fixed Tracks

Grid layouts can prevent cards from changing size unpredictably.

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
}

.product-card__image {
  aspect-ratio: 1 / 1;
}

The image area remains stable even before the image loads.

Container Queries and Responsive Reservations

Mobile and desktop often need different reserved heights.

.hero {
  min-height: 520px;
}

@media (max-width: 767px) {
  .hero {
    min-height: 640px;
  }
}

Do not assume the desktop height works on mobile. Mobile text wraps into more lines, ads may use different sizes, and stacked layouts often need more vertical space.

Content Visibility and Intrinsic Size

For below-the-fold content, content-visibility: auto can improve rendering performance. When using it, define a realistic intrinsic size so the browser can reserve space before rendering the section.

.below-fold-section {
  content-visibility: auto;
  contain-intrinsic-size: 600px;
}

This is useful for long pages with expensive sections, but the intrinsic size must be close to the real rendered size. If it is far off, the page may still shift when the section becomes visible.

Practical Implementation Examples

Stable Hero Image

<section class="hero">
  <img
    class="hero-image"
    src="/images/hero.webp"
    width="1440"
    height="720"
    alt="Website performance dashboard"
    fetchpriority="high"
  >
  <h1>Analyze Your Website Performance</h1>
</section>
.hero {
  display: grid;
  gap: 24px;
}

.hero-image {
  width: 100%;
  height: auto;
  display: block;
}

This reserves space for the hero image and also helps LCP because the browser can prioritize the image.

Stable Card Grid

<article class="post-card">
  <a href="/blog/example">
    <img
      src="/images/blog-cover.jpg"
      width="800"
      height="450"
      alt="Blog cover"
    >
    <h2>How to Improve Core Web Vitals</h2>
  </a>
</article>
.post-card img {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
  object-fit: cover;
}

This prevents each card from growing after the image loads.

Stable Placeholder for API Content

<section class="reviews" aria-busy="true">
  <div class="review-placeholder"></div>
  <div class="review-placeholder"></div>
  <div class="review-placeholder"></div>
</section>
.reviews {
  min-height: 360px;
}

.review-placeholder {
  height: 96px;
  margin-bottom: 16px;
  background: #eee;
}

When real reviews load, replace the placeholders inside the same reserved container.

Stable Cookie Banner

If the banner should push content down, reserve the space from the initial render.

<body class="has-cookie-banner">
  <div class="cookie-banner">
    This site uses cookies.
  </div>
  <main>
    ...
  </main>
</body>
.cookie-banner {
  min-height: 56px;
}

.has-cookie-banner main {
  padding-top: 0;
}

If the banner is not essential to document flow, overlay it instead.

.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  min-height: 64px;
  z-index: 1000;
}

An overlay avoids pushing content, but make sure it does not block important actions.

WordPress Implementation Guidance

WordPress sites commonly experience CLS from themes, page builders, lazy loading plugins, ads, embeds, and missing image dimensions.

Here are the most important areas to check.

Add Width and Height to Images

Modern WordPress usually outputs image dimensions for media library images, but problems can still happen with:

Inspect the final HTML, not just the editor view.

Good output should look like this:

<img
  src="image.jpg"
  width="1200"
  height="675"
  alt="Example"
  loading="lazy"
>

If your theme or plugin strips dimensions, fix the template or enable a reliable "add missing image dimensions" feature in your performance plugin. This is one of the same practical checks used in a full WordPress Web Vitals optimization workflow.

Using FlyingPress to Reduce CLS

FlyingPress can help reduce CLS automatically on many WordPress sites, especially when the shifts are caused by images, iframes, lazy loading behavior, fonts, or delayed rendering.

The most relevant FlyingPress features for layout stability are:

FlyingPress is useful because it solves several common WordPress CLS issues without needing custom code for every template. However, it cannot fix every layout shift automatically. Ads, cookie banners, page builder sections, sliders, and custom JavaScript widgets still need manual testing.

If you are choosing between caching plugins, the FlyingPress vs WP Rocket comparison explains how both plugins fit into Core Web Vitals optimization.

Reserve Space for Featured Images

For blog posts, category pages, and archive cards, featured images should have consistent ratios.

.post-thumbnail {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.post-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

This is especially important on archive pages where many cards load together.

Reserve Space for Ads

If you use AdSense, Google Ad Manager, or another ad network, define slot sizes in your theme.

.single-post-ad {
  min-height: 280px;
  margin: 32px 0;
}

@media (max-width: 767px) {
  .single-post-ad {
    min-height: 320px;
  }
}

Avoid injecting ad containers into the article after load without a reserved slot.

Reserve Space for Embeds

WordPress embeds can load from YouTube, Twitter/X, Instagram, Maps, and other third-party platforms. Wrap these embeds in stable containers where possible.

.wp-block-embed__wrapper {
  aspect-ratio: 16 / 9;
}

.wp-block-embed__wrapper iframe {
  width: 100%;
  height: 100%;
}

Some embeds do not have a fixed ratio. In those cases, use min-height based on the typical rendered height.

Check Page Builder Sections

Page builders often load sliders, tabs, animations, and dynamic widgets after the initial render.

Check:

If a widget appears late, give its section a minimum height or replace it with server-rendered content.

Good vs Bad Approaches

Element Bad Approach Good Approach
Images <img src="photo.jpg"> Add width, height, and responsive CSS
Hero image CSS background with no container height Use an image element or reserve hero height
Responsive images Different srcset ratios Keep the same ratio or define ratios per breakpoint
Ads Insert ad container after load Render reserved ad slot in initial HTML
Embeds Raw iframe with no dimensions Wrap iframe with aspect-ratio
API content Empty div that expands later Use skeletons or min-height
Fonts Custom font with poor fallback Use close fallback, preload critical font, tune metrics
Banners Inject at top after load Reserve space or overlay carefully
Product cards Image height based on load Fixed media ratio in each card
Infinite scroll Insert content above current viewport Append below or use user-initiated loading

Comparison of Space Reservation Techniques

Technique Best For Benefit Risk
width and height attributes Images and videos Browser calculates aspect ratio early Wrong dimensions can still cause shift
aspect-ratio Media containers, cards, embeds Simple responsive space reservation Needs correct ratio
min-height Ads, widgets, dynamic sections Prevents zero-height containers Can leave blank space if overestimated
Skeleton UI API-loaded components Preserves layout and improves perceived loading Must match final layout closely
Fixed grid/card media areas Product grids and article cards Keeps repeated layouts stable Cropping may require object-fit
Font preloading Critical above-the-fold fonts Reduces late font swaps Too many preloads can hurt LCP
Font metric overrides Text-heavy layouts Reduces reflow between fallback and web font Requires careful font metric calculation
contain-intrinsic-size Below-the-fold sections Reserves space with deferred rendering Bad estimates can still shift

Desktop and Mobile Layout Shift Concerns

CLS should be checked separately on desktop and mobile.

Mobile pages often have higher layout shift risk because:

Desktop pages have different issues:

Do not test only one viewport. A page can have excellent CLS on desktop and poor CLS on mobile.

Also, remember that some navigations do not behave like fresh page loads. For example, Back/Forward Cache can restore a page from memory and avoid many shifts that would otherwise happen during a normal load.

How to Test CLS Improvement

You should measure layout stability before and after making changes.

Use both lab and field data where possible.

1. Run a Baseline Test

Start by testing the current page with a Web Vitals tool such as the SpeedVitals Website Speed Test, PageSpeed Insights, Lighthouse, or Chrome DevTools.

Record:

Do not compare results from different test conditions.

2. Identify the Elements That Shift

In Chrome DevTools:

  1. Open the page.
  2. Open DevTools.
  3. Go to the Performance panel.
  4. Start recording.
  5. Reload and interact with the page.
  6. Stop recording.
  7. Check the Layout Shifts track.

DevTools can show which elements moved and when the shift happened.

Important: the shifted element is not always the root cause. For example, a paragraph may be listed as shifted because an ad above it appeared late.

3. Test Mobile and Desktop Separately

Run tests for:

CLS issues are often more visible on slower connections because images, fonts, ads, and JavaScript arrive later.

4. Compare Before and After

After implementing space reservation, compare the same page under the same conditions.

Look for:

Do not rely on a single run. Run multiple tests to confirm the improvement is repeatable.

5. Check Field Data

Lab tools are useful for debugging, but field data shows what real users experience.

Use:

Field CLS can include shifts that happen after initial load, such as shifts during scroll, lazy loading, route changes, or delayed third-party scripts.

Best Practices to Prevent Layout Shift

Follow these rules for most websites:

Common Mistakes to Avoid

Relying Only on Lazy Loading

Lazy loading improves bandwidth usage, but it does not automatically prevent layout shift.

This is bad:

<img src="/image.jpg" loading="lazy" alt="Example">

This is better:

<img
  src="/image.jpg"
  loading="lazy"
  width="800"
  height="450"
  alt="Example"
>

Lazy-loaded images still need dimensions.

Reserving Too Little Space

If a placeholder is much smaller than the final content, the page will still shift.

.widget-placeholder {
  min-height: 100px;
}

If the final widget is usually 400px tall, this only reduces the shift. It does not prevent it.

Collapsing Empty Ad Slots

If an ad slot reserves 280px and then collapses to 0px when no ad is returned, the content below moves upward.

That still contributes to visual instability.

A better approach is to keep the space, use a fallback, or collapse only when the slot is outside the viewport and unlikely to affect the current user experience.

Using Background Images Without Height

CSS background images do not define layout dimensions by themselves.

Bad:

.hero {
  background-image: url("/hero.jpg");
}

Better:

.hero {
  min-height: 520px;
  background-image: url("/hero.jpg");
  background-size: cover;
  background-position: center;
}

If the image is important content or the LCP element, consider using an actual <img> element instead.

Animating Layout Properties

Avoid animating properties that affect layout, such as:

Prefer transform-based animations:

.panel {
  transform: translateY(16px);
  opacity: 0;
  transition: transform 200ms ease, opacity 200ms ease;
}

.panel.is-visible {
  transform: translateY(0);
  opacity: 1;
}

Transform animations do not push surrounding content around.

Practical CLS Fixing Workflow

Here is a reliable process for fixing layout shift on any website:

  1. Test the page on mobile and desktop.
  2. Find the largest layout shift events.
  3. Identify what appeared, resized, or changed before the shifted element moved.
  4. Add dimensions, aspect ratio, min-height, or a skeleton.
  5. Retest under the same conditions.
  6. Repeat for post-load shifts during scroll and interaction.
  7. Monitor field CLS after deployment.

Start with the biggest visible shifts first. Fixing one above-the-fold ad, hero image, or font swap can often make a larger difference than many small changes lower on the page.

Conclusion

Reserving space is one of the most practical ways to prevent layout shift.

The browser cannot create a stable layout if important elements have unknown sizes. Images need dimensions. Embeds need ratios. Ads need slots. Dynamic components need placeholders. Fonts need predictable fallback behavior.

For most websites, the biggest wins come from:

A stable page feels faster, more polished, and easier to use. If you are optimizing Core Web Vitals, do not treat layout shift as a cosmetic issue. Reserve the space early, verify the improvement with real testing, and keep monitoring CLS as your design, ads, plugins, and content change.