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

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

  • By
    Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

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.

  5. Thanks a Lot David,

    I have issue with a WP “Accordion” Plugin from @siteorigin, as usual every body pointed the finger at other plugins, fixed the iframe issue, the plugin set the width & height of the Iframe to 0 if the accordion was set to be closed while page load.

    /* .iframe-container */
    .sow-accordion-panel-content .jetpack-video-wrapper {
      	position: relative;
        overflow: hidden;
        padding-top: 56.25%;
    }
    
    /* css for the iframe */
    .sow-accordion-panel-content .su-column iframe {
         position: absolute;
        top: 0;
        left: 0;
        width: 100% !important;
        height: 100% !important;
        border: 0;
    }
    

    thanks once again..

  6. Ilya

    Hi David,
    thanks a lot for your solution.
    I had a little problem using it. Namely, when I used it just as you suggested in my project, I got a black frame on the top and bottom of the video. Long story short, it turned out that my video container had a non-zero height (I didn’t define height for it at all), therefore the ratio of 56.25% didn’t work properly. So, to make this solution perfect I would add a height of 0:

    .iframe-container {
        position: relative;
        overflow: hidden;
        height: 0;
        padding-top: 56.25%;
    }
    
  7. Hi, I’m not very sophisticated in CSS and appreciate Dave’s post which seems to work well for me in making the Youtube video responsive. But I’m getting a lot of blank white space between the bottom of my responsive embedded video and the text that follows it. I’ve removed all and tags after the container so the space seems defined by the iframe somehow. When I change the padding top to a smaller percent, the space under the video gets smaller but so does the video. I’m coding this by hand so not using any framework. Any suggestions how to remove the large white space gap between the video and the text that follows? thanks from a novice.

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