How to Properly Reserve Space for Images and Iframes

Here’s a confession: for the longest time, I thought “reserving space” was just a fancy way of saying “use aspect-ratio and call it a day.” Turns out, it’s a whole category of problems on its own, and iframes in particular have a nasty habit of breaking rules that images happily follow. So let’s get into it properly.

Images First — The Easy Case

For a plain <img> tag, the fix is genuinely simple, and I covered the core of it in the last post. But since this is the “reserve space” post specifically, let’s zoom in on the HTML side of things, because I think it gets undersold.

<img src="banner.jpg" width="1200" height="600" alt="Banner">

Just adding those width and height attributes — even without a single line of CSS — tells the browser the image’s intrinsic ratio before the file downloads. Modern browsers use this to compute an aspect ratio automatically. It’s honestly one of the cheapest wins in all of web performance, and I still see it skipped constantly on client sites I audit.

Now, the Annoying Case: Iframes

Iframes are where things get messy, because unlike an <img>, you often don’t control what’s inside them. YouTube embeds, Google Maps, payment widgets, chat plugins — you’re renting space in someone else’s box.

Here’s my go-to approach:

.iframe-wrapper {
  aspect-ratio: 16 / 9;
  width: 100%;
}

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

Wrap the iframe, set the ratio on the wrapper, stretch the iframe to fill it. I’ve used this exact pattern on probably a dozen client projects, and it hasn’t failed me yet.

What About Iframes With Unpredictable Height?

This is the part that trips people up. Some embeds — think comment widgets, certain chat tools, or CMS-injected forms — genuinely don’t have a fixed ratio. Their height depends on their content, which you can’t know in advance.

For these, I lean on a rougher but honest technique: estimate a minimum height based on typical content, and accept some shift as a trade-off.

Embed TypeMy Typical Reserved HeightWhy
Video (16:9)Calculated via aspect-ratioFixed, predictable ratio
Google MapsCalculated via aspect-ratioFixed, predictable ratio
Comment widgets (Disqus, etc.)400-600px min-heightContent-dependent, estimate only
Chat/support widgetsFixed via position: fixedOverlay, doesn’t push content
Payment forms (Stripe, etc.)300-450px min-heightVaries by payment method shown

I’m not going to pretend this table is scientific — these numbers come from watching real embeds on real sites over time, not some official spec. But having any reasonable estimate beats having zero reserved space, every single time.

A Technique I Genuinely Like: Skeleton Placeholders

For embeds where height is unpredictable, I’ve started reserving space with a light gray skeleton block that matches my estimated minimum height, then letting the real content replace it once it loads. It doesn’t eliminate shift entirely if my estimate is off, but it drastically reduces both the visual jarring and the actual CLS number, since the shift happens against a placeholder instead of jumping other content around.

Third-Party Scripts: The Sneakiest Offender

I want to call this out specifically because it burned me once on a real project: third-party scripts that inject their own iframe after your page has already rendered — think consent banners, some chat widgets, certain ad networks — don’t care about your carefully planned layout at all. They just show up and shove things around.

My rule of thumb now:

  1. Reserve space for third-party embeds before the script loads, using a placeholder div with an estimated size
  2. Load these scripts with async or defer where possible, so they don’t block rendering
  3. Test with the actual third-party script active — not a mockup — because vendors change their embed sizes more often than you’d think

Wrapping Up

If I had to sum up this whole post in one sentence, it’d be this: images are a solved problem, iframes are a negotiation. You can’t always control what shows up inside someone else’s embed, but you can absolutely control how much guessing your layout has to do while it waits. Reserve space generously, estimate honestly, and treat every third-party script as a potential layout troublemaker until proven otherwise.

Next time, we’re diving into lazy loading — and how to get the performance benefits without reintroducing the exact shift problems we just fixed.

By Dana Kowalski

I’m a front-end developer with 8 years of experience building and optimizing production websites — everything from small marketing sites to e-commerce platforms handling real traffic and real revenue.

Leave a Reply

Your email address will not be published. Required fields are marked *