Responsively Sizing Iframes


Published: 2018-12-22
Updated: 2018-12-24
Web: https://fritzthecat-blog.blogspot.com/2018/12/responsively-sizing-iframes.html


I discovered the techniques explained here on Ben Marshal's and John Surdakovski's pages on the web. It is about "responsive" iframe HTML elements, meaning that an embedded iframe should resize when the browser window gets resized.

WARNING: Studying this article on a mobile could lead to misunderstandings, because all example iframes may have the same size then, also you won't be able to resize the browser window.

Following shows how a video player embedded in an iframe looks when you don't assign pixel values to width and height attributes:

  <iframe
src="https://www.youtube.com/embed/-p3h2Xcay_o"
frameborder="0"
allowfullscreen>
</iframe>

Would be nice now if it filled the whole width, keeping its aspect ratio, and grew bigger when the browser window grows bigger.

But there is a problem with aspect ratio (= height / width). The iframe element can host a whole HTML page, and an HTML page has no height by default (although it is aware of width). That's the reason why you always find the hardcoded width and height attributes on iframes, they express the aspect ratio, but, as a side effect, they also fix its size: <iframe width="640" height="360" ...>. Thus an iframe having these attributes would not resize dynamically, and without them it has no aspect ratio.

Nevertheless the video player has an aspect ratio, only its wrapping iframe does not know about it, because it was made for HTML pages. Tricks like setting the CSS height: auto; and width: 100%; do not help, this looks like the following:

  <iframe
style="width: 100%; height: auto;"
src="https://www.youtube.com/embed/-p3h2Xcay_o"
frameborder="0"
allowfullscreen>
</iframe>

You see that the height remained small, while stretching the width actually worked. Setting height to 100% won't help either, because this would work just when all parents' heights had been set to a defined value.

So we need a technique that gives us a rectangle which sizes dynamically. What people use is a parent block element that has a vertical padding percentage, and then putting the iframe onto that padding rectangle, stretching it to full-size. We need to study some basics to understand that.

On the CSS Box Model specification we find for padding-xxx:

Percentages: refer to logical width of containing block.
Logical width: refers to the physical width (horizontal dimension) in horizontal writing modes, and to the physical height (vertical dimension) in vertical writing modes.

Thus a percentage in some padding takes the dynamically calculated dimension as base. So what we need is a parent element with such a dynamic padding rectangle, and then place the iframe absolutely over it. Consider following CSS and HTML.

  .iframe-container
{
position: relative;
}

.youtube-aspect-ratio
{
/* The default YouTube aspect-ratio: height / width */
padding-bottom: 56.25%;
}

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

This CSS defines three rule-sets:

  1. Any element with class iframe-container will have position: relative; that is to be a parent for an absolutely positioned child element.

  2. Any element with class youtube-aspect-ratio will have padding-bottom: 56.25%; that means it takes 56.25% of the width of the element! This is the dynamic rectangle where the iframe can go to. It could also have been the padding-top.

  3. An iframe inside an element with class iframe-container will fill all available space given by the parent (width: 100%; height: 100%;) and be attached to top-left corner through position: absolute; and top and left set to zero. It will not be affected by the undefined height of its parent element, because absolutely positioned elements go out of the normal layout flow. The height of its parent will be zero when nothing is inside.
  <div class="iframe-container youtube-aspect-ratio">
<iframe
src="https://www.youtube.com/embed/-p3h2Xcay_o"
frameborder="0"
allowfullscreen>
</iframe>
</div>

This HTML wraps the iframe into a div element with class iframe-container, and it adopts the youtube-aspect-ratio of the video-player as the aspect ratio for the padding-bottom rectangle. Mind that there are no width and height HTML-attributes on the iframe, just the according CSS-properties were set to 100% through the rule-set above.

Here is the outcome:

That's it!
Resize the browser window to try it out. The video player should resize proportionally, keeping its aspect ratio.
You will want to create different aspect ratio CSS-classes for other links embedded in further iframes.





ɔ⃝ Fritz Ritzberger, 2018-12-22