Responsive IFRAMEs

By  on  

Responsive web design revolutionized the web and spurred a movement away from native apps to web apps easily customizable for a mobile environment.  We use media queries and non-pixel-based dimensions to make responsive design easier; in fact, img { max-width: 100% } is one of my favorite CSS snippets.  IFRAME elements cause an all together different problem because they aren't restricted to dimensions.  I found an amazing post by Gregory Gan that describes an ingenious method for responsive IFRAMEs and I wanted to share it with all of you!

The HTML

To make your IFRAME responsive you'll need to wrap it in a <div>:

<div class="iframe-container">
  <iframe width="1425" height="559" src="https://www.youtube.com/embed/BS4ojxHC1EM"></iframe>
</div>

The<div> will be the frame reactive frame of reference for the IFRAME.

The CSS

The parent <div> has an interesting set of CSS:

.iframe-container {
    position: relative;
    overflow: hidden;
    padding-top: 56.25%;
}

The padding-top is the interesting bit; setting the padding-top to a percentage of height 9 / width 16 allows us to keep a desirable ratio.  This ratio matches a YouTube height to width ratio, but you can use any ratio to match the ratio of your IFRAME usage.

Next you define the IFRAME's CSS:

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

The IFRAME's CSS is unremarkable since the<div> does most of the work;  positioning the IFRAME as absolute and setting its width and height to 100% constrains the element to the DIV's reactive dimensions.

The CSS above is all it takes to turn a problematic, static IFRAME into a reactive element that's as easy to manipulate as an image.  Kudos to Gregory Gan for his amazing post and tip!

Recent Features

Incredible Demos

Discussion

  1. R Geuze

    Very useful trick for displaying responsive (video) embeds.

    Note that, unlike for many other elements, using right: 0; bottom: 0; instead of width:100%;height:100% will not (always) work as expected for iframes.

    If you have access to the iframe target site as well, you can also write a solution based on the postMessage API to send the inner content height to the parent site.
    https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

  2. Back in 2016 I used a JS-approach to do the same. Have a look :)

    https://codepen.io/tomlutzenberger/pen/oYByjE/

  3. Raph

    This is the technique used by Bootstrap (3+). They call it “responsive embed” and provide 4:3 and 16:9 ratios.

    See the doc here : https://getbootstrap.com/docs/3.3/components/#responsive-embed
    Sources : https://github.com/twbs/bootstrap/blob/v3.3.7/less/responsive-embed.less

  4. Ron

    Ben Marshall wrote an article about this subject in March 2014 and Updated it recently in May. His code is the same as David’s.

    He also posed the question — what if the aspect ratio is not known? Then you need a little bit of javascript. His solution is similar to Tom’s Codepen javascript above.

    // Find all iframes
    var $iframes = $( "iframe" );
    
    // Find & save the aspect ratio for all iframes
    $iframes.each(function () {
      $( this ).data( "ratio", this.height / this.width )
        // Remove the hardcoded width & height attributes
        .removeAttr( "width" )
        .removeAttr( "height" );
    });
    
    // Resize the iframes when the window is resized
    $( window ).resize( function () {
      $iframes.each( function() {
        // Get the parent container's width
        var width = $( this ).parent().width();
        $( this ).width( width )
          .height( width * $( this ).data( "ratio" ) );
      });
    // Resize to fix all iframes on page load.
    }).resize();
    

    There are other types of embedded iFrames of the “media” variety. All of the frameworks and preset ratios are even limiting. Raph’s cited Bootstrap methods above are examples of only two embed ratios.

    Now the reason I am here! LOL

    I needed to have a responsive iFrame for a chat room. It had to stick to the to the sides (that part is easy). It also had to stick to the bottom of the header & the top the footer. And be resizable.

    That snippet of code made it all work. The behaviour is much like a frameset with fixed height top and bottom frames.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!