Published
Updated
Comments0

Responsive iframes without wrappers did you say?

⚠️ This article is outdated: Don’t use jQuery. Also, this JS technique does not work well when server side rendering.

Responsive images are pretty intuitive; apply max-width: 100% and voila. But what to do about those pesky iframes (video embeds!) whose height does not remain in ratio to width when responding down? The most common technique you will come across dates back years and involves wrappers styled to preserve a hard-coded intrinsic aspect ratio (typically 16:9). Most of the popular scripts such as fitvids.js utilize this technique.

This approach sucks for few reasons:

  1. Wrappers may not play nice with your current setup. Perhaps your videos are added, sized and positioned via a CMS WYSIWYG.
  2. Is ~75 lines of jQuery really necessary?
  3. Most implementations stretch videos to fill their container’s width, disrespecting any inline dimensions your iframe should have.
  4. Non-semantic wrappers that bloat your inspector suck.

Given typical HTML like this (inline dimensions required):

<iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ?rel=0" frameborder="0" allowfullscreen></iframe>

With this CSS:

iframe {
  max-width: 100%;
}

Here is the magic jQuery solution:

// Apply CSS height to every iframe in correct ratio to it’s current width
function resizeIframes() {
  // Loop over every iframe on the page
  $('iframe').each(function() {
    // Get the iframe’s intended aspect ratio via it’s inline dimensions
    var ratio = $(this).attr('height') / $(this).attr('width')
    // Apply a CSS height that is in correct ratio to it’s current width
    $(this).css('height', $(this).width() * ratio)
  })
}

// Pop off an initial resize when the page loads
resizeIframes()

// Update iframes each time the window is resized
$(window).resize(function() {
  resizeIframes()
})

But thats not so magic! Aren’t window resize event listeners terrible for performance?

Short answer, not like this. Try it yourself! So what if a really crappy PC lags a bit resizing the browser window? To me the pro’s outweigh the cons. No junky wrapper, minimal CSS and tiny JS (compared to scripts like fitvids.js). It will have no adverse effect on you current layout and respects the inline sizing as much as possible. This technique should be compatible with almost any project, especially if it were converted to vanilla JS.

The catch is that you will need to call resizeIframes() any time new iframes are dynamically inserted onto the page, or when a dramatic layout change resizes iframes without resizing the window.

I debated this technique in the Github issues area for Todd Motto’s fluidvids.js a little while back.