How to: Responsive iframes

Daniel Goshev
Nov 10, 2021
Categories:CSS

Introduction

The iframe tag is used quite often around the web. Whether you need to add a social media widget to your personal blog, embed a video or something else you are probably going to be using an iframe. Getting those elements to look good across multiple resolutions, however, might be a tricky task.

The code can also be found in JSFiddle.

Let's do it!

We'll start off with a simple iframe. For the means of this example we will use a YouTube embed for the Python 101 Forever course introduction. Here is what we are starting with.

<iframe 
  src="https://www.youtube.com/embed/HE4M_0ZskqA" 
  title="YouTube video player" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen
></iframe>

As a result, we got a small box with the video. At this size, however, it's not very usable.

That shouldn't be an issue for us, right? With a quick check in the MDN Web Docs we can see that the iframe tag supports attributes like width and height.

We'll throw these in so we can get a full-sized, usable version of the video. Let's say our screen is 1920x1080.

<iframe 
  width="1920" 
  height="1080" 
  src="https://www.youtube.com/embed/HE4M_0ZskqA" 
  title="YouTube video player" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen
></iframe>

Looks pretty good! Until we hit a screen size which can't fit our iframe. In those cases we would get a side-scroll and nobody likes side-scrolls, do they?

This shouldn't be a big issue either, right? We can just set the width to 100%.

<iframe 
  width="100%" 
  height="1080" 
  src="https://www.youtube.com/embed/HE4M_0ZskqA" 
  title="YouTube video player" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen
></iframe>

We lost the side-scroll but now our thumbnail is being cut off. We want to maintain the aspect ratio of the video while still keeping the video as wide as our screen.

Time to get our hands dirty

We'll start off by wrapping our iframe with a div which will have the container class.

<div class="container">
  <iframe
    width="100%"
    height="1080"
    src="https://www.youtube.com/embed/HE4M_0ZskqA"
    title="YouTube video player" frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen
  ></iframe>
</div>

Second, we'll add some CSS for our container.

.container {
  position: relative;
  width: 100%; // The width is 100% due to us using a div, but this way it's more explicit.
}

.container > iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

The iframe styles have the width and height so we can drop them from the HTML code. This is what we're left with.

<div class="container">
  <iframe
    src="https://www.youtube.com/embed/HE4M_0ZskqA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
    allowfullscreen
  ></iframe>
</div>

You might've come so far and figured out we have a blank screen. Our iframe is gone.

Throwing border: 1px solid red; in the container styles shows us that our element is still there, it just has a height equal to 0.

The secret sauce

It's the time for the secret sauce, the trick, that will help us accomplish the task of having a responsive iframe. We'll add padding-top to the container styles.

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
}

.container > iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Voila! We have our iframe with the width of our screen and the 16:9 aspect ratio. Even if we change the width of our screen the iframe sizes itself to match the width while keeping the proportions right.

But how does it work?

The padding-top of 56.25% might sound random, but it certainly is not. The percentage padding values are calculated based on the element width. We are trying to achieve the aspect ratio of 16:9. If we come to divide 9 by 16 we would get 0.5625, or otherwise said - 9 is 56.25% of 16.

Using the relation between the aspect ratios you can calculate the padding-top you need for your iframe. For example, if we're using a video with the 4:3 aspect ratio we would have to use padding-top of 75%.

TL;DR (Give me the code)

This is the code we end up with.

<div class="container">
  <iframe 
    src="https://www.youtube.com/embed/HE4M_0ZskqA" 
    title="YouTube video player" 
    frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
    allowfullscreen
  ></iframe>
</div>
.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
}

.container > iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

The code can also be found in JSFiddle.

Conclusion

Making an iframe responsive is a common task that might be hard, if you don't know this trick.

If you don't need Internet Explorer support, you can use the aspect-ratio CSS property instead.

Hope you found this article to be helpful!