[javascript] make iframe height dynamic based on content inside- JQUERY/Javascript

I am loading an aspx web page in an iframe. The content in the Iframe can be of more height than the iframe's height. The iframe should not have scroll bars.

I have a wrapper div tag inside the iframe which basically is all the content. I wrote some jQuery to make the resize happen :

$("#TB_window", window.parent.document).height($("body").height() + 50);

where TB_window is the div in which the Iframe is contained.

body - the body tag of the aspx in the iframe.

This script is attached to the iframe content. I am getting the TB_window element from the parent page. While this works fine on Chrome, but the TB_window collapses in Firefox. I am really confused/lost on why that happens.

This question is related to javascript jquery asp.net iframe

The answer is


Other answers were not working for me so i did some changes. Hope this will help

$('#iframe').on("load", function() {
    var iframe = $(window.top.document).find("#iframe");
    iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});

I found that the accepted answer didn't suffice, since X-FRAME-OPTIONS: Allow-From isn't supported in safari or chrome. Went with a different approach instead, found in a presentation given by Ben Vinegar from Disqus. The idea is to add an event listener to the parent window, and then inside the iframe, use window.postMessage to send an event to the parent telling it to do something (resize the iframe).

So in the parent document, add an event listener:

window.addEventListener('message', function(e) {
  var $iframe = jQuery("#myIframe");
  var eventName = e.data[0];
  var data = e.data[1];
  switch(eventName) {
    case 'setHeight':
      $iframe.height(data);
      break;
  }
}, false);

And inside the iframe, write a function to post the message:

function resize() {
  var height = document.getElementsByTagName("html")[0].scrollHeight;
  window.parent.postMessage(["setHeight", height], "*"); 
}

Finally, inside the iframe, add an onLoad to the body tag to fire the resize function:

<body onLoad="resize();">

This one is useful when you require a solution with no jquery. In that case you should try adding a container and set a padding to it in percentages

HTML example code:

<div class="iframecontainer">
    <iframe scrolling="no" src="..." class="iframeclass"width="999px" height="618px"></iframe>
</div>

CSS example code:

.iframeclass{
    position: absolute;
    top: 0;
    width: 100%;
}

.iframecontainer{
    position: relative;
    width: 100%;
    height: auto;
    padding-top: 61%;
}

Sample using PHP htmlspecialchars() + check if height exists and is > 0:

$my_html_markup = ''; // Insert here HTML markup with CSS, JS... '<html><head></head><body>...</body></html>'
$iframe = '<iframe onload="if(this.contentWindow.document.body.scrollHeight) {this.height = this.contentWindow.document.body.scrollHeight;}" width="100%" src="javascript: \''. htmlspecialchars($my_html_markup) . '\'"></iframe>';

just make iframe container position:absolute and iframe will automatically change its height according to its content

<style>
   .iframe-container {
       display: block;
       position: absolute;
       /*change position as you need*/
       bottom: 0;
       left: 0;
       right: 0;
       top: 0;
   }
   iframe {
       margin: 0;
       padding: 0;
       border: 0;
       width: 100%;
       background-color: #fff;
   }
 </style>
 <div class="iframe-container">
     <iframe src="http://iframesourcepage"></iframe>
 </div>

A slightly improved answer to Aristos...

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
  }
</script>  

Then declare in your iframe as follows:

<iframe onload="resizeIframe(this)" ...

There are two minor improvements:

  1. You don't need to get the element via document.getElementById - as you already have it in the onload callback.
  2. There's no need to set the iframe.height = "" if you're going to reassign it in the very next statement. Doing so actually incurs an overhead as you're dealing with a DOM element.

Edit: If the content in the frame is always changing then call:

parent.resizeIframe(this.frameElement); 

from within the iframe after the update. Works for same origin.

Or to auto detect:

  // on resize
  this.container = this.frameElement.contentWindow.document.body;

  this.watch = () => {
    cancelAnimationFrame(this.watcher);

    if (this.lastScrollHeight !== container.scrollHeight) {
      parent.resizeIframeToContentSize(this.frameElement);  
    }
    this.lastScrollHeight = container.scrollHeight;
    this.watcher = requestAnimationFrame(this.watch);
  };
  this.watcher = window.requestAnimationFrame(this.watch);

Rather than using javscript/jquery the easiest way I found is:

_x000D_
_x000D_
<iframe style="min-height:98vh" src="http://yourdomain.com" width="100%"></iframe>
_x000D_
_x000D_
_x000D_

Here 1vh = 1% of Browser window height. So the theoretical value of height to be set is 100vh but practically 98vh did the magic.


Add this to the iframe, this worked for me:

onload="this.height=this.contentWindow.document.body.scrollHeight;"

And if you use jQuery try this code:

onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"

A slightly improved answer to BlueFish...

function resizeIframe(iframe) {
    var padding = 50;
    if (iframe.contentWindow.document.body.scrollHeight < (window.innerHeight - padding))
        iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    else
        iframe.height = (window.innerHeight - padding) + "px";
}

This takes in consideration the height of the windows screen(browser, phone) which is good for responsive design and iframes that have huge height. Padding represents the padding you want above and below the iframe in the case it goes trough whole screen.


You can refer related question here - How to make width and height of iframe same as its parent div?

To set dynamic height -

  1. We need to communicate with cross domain iFrames and parent
  2. Then we can send scroll height/content height of iframe to parent window

And codes - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8


I found the answer from Troy didn't work. This is the same code reworked for ajax:

$.ajax({                                      
    url: 'data.php',    
    dataType: 'json',                             

    success: function(data)
    {
        // Put the data onto the page

        // Resize the iframe
        var iframe = $(window.top.document).find("#iframe");
        iframe.height( iframe[0].contentDocument.body.scrollHeight+'px' );
    }
});

$(document).height() // - $('body').offset().top

and / or

$(window).height()

See Stack Overflow question How to get the height of a body element.

Try this to find the height of the body in jQuery:

if $("body").height()

It doesn't have a value if Firebug. Perhaps that's the problem.


jQuery('.home_vidio_img1 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery(this).replaceWith(video);
});

jQuery('.home_vidio_img2 img').click(function(){
    video = <iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>;
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img3 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img4 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

I am using jQuery and the code below working for me,

var iframe = $(window.top.document).find("#iframe_id_here");
iframe.height(iframe.contents().height()+'px' );

in my project there is one requirement that we have make dynamic screen like Alignment of Dashboard while loading, it should display on an entire page and should get adjust dynamically, if user is maximizing or resizing the browser’s window. For this I have created url and used iframe to open one of the dynamic report which is written in cognos BI.In jsp we have to embed BI report. I have used iframe to embed this report in jsp. following code is working in my case.

<iframe src= ${cognosUrl} onload="this.style.height=(this.contentDocument.body.scrollHeight+30) +'px';" scrolling="no" style="width: 100%; min-height: 900px; border: none; overflow: hidden; height: 30px;"></iframe>

The simple solution is to measure the width and height of the content area, and then use those measurements to calculate the bottom padding percentage.

In this case, the measurements are 1680 x 720 px, so the padding on the bottom is 720 / 1680 = 0.43 * 100, which comes out to 43%.

.canvas-container {    
    position: relative;
    padding-bottom: 43%; // (720 ÷ 1680 = 0.4286 = 43%)
    height: 0;
    overflow: hidden;   
}

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

All other answers are correct but what if the iframe has some dynamic content like a map that loads later and dynamically changes your iframe scroll height. This is how I achieved it.

var iFrameID = document.getElementById('idIframe');

intval =  setInterval(function(){
if(iFrameID.scrollHeight == iFrameID.contentWindow.document.body.scrollHeight){
     clearInterval(intval);
}else{
   iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
  }
},500)

I simply wrap the code inside setInterval which matches the iframe scroll height with iframe content scroll height then clear the interval.


Just in case this helps anyone. I was pulling my hair out trying to get this to work, then I noticed that the iframe had a class entry with height:100%. When I removed this, everything worked as expected. So, please check for any css conflicts.


you could also add a repeating requestAnimationFrame to your resizeIframe (e.g. from @BlueFish's answer) which would always be called before the browser paints the layout and you could update the height of the iframe when its content have changed their heights. e.g. input forms, lazy loaded content etc.

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    window.requestAnimationFrame(() => resizeIframe(iframe));
  }
</script>  

<iframe onload="resizeIframe(this)" ...

your callback should be fast enough to have no big impact on your overall performance


There are four different properties you can look at to get the height of the content in an iFrame.

document.documentElement.scrollHeight
document.documentElement.offsetHeight
document.body.scrollHeight
document.body.offsetHeight

Sadly they can all give different answers and these are inconsistant between browsers. If you set the body margin to 0 then the document.body.offsetHeight gives the best answer. To get the correct value try this function; which is taken from the iframe-resizer library that also looks after keeping the iFrame the correct size when the content changes,or the browser is resized.

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        function getPixelValue(value) {
            var PIXEL = /^\d+(px)?$/i;

            if (PIXEL.test(value)) {
                return parseInt(value,base);
            }

            var 
                style = el.style.left,
                runtimeStyle = el.runtimeStyle.left;

            el.runtimeStyle.left = el.currentStyle.left;
            el.style.left = value || 0;
            value = el.style.pixelLeft;
            el.style.left = style;
            el.runtimeStyle.left = runtimeStyle;

            return value;
        }

        var 
            el = document.body,
            retVal = 0;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            retVal =  document.defaultView.getComputedStyle(el, null)[prop];
        } else {//IE8 & below
            retVal =  getPixelValue(el.currentStyle[prop]);
        } 

        return parseInt(retVal,10);
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}

To add to the chunk of window that seems to cut off at the bottom, especially when you don't have scrolling I used:

function resizeIframe(iframe) {
    var addHeight = 20; //or whatever size is being cut off
    iframe.height = iframe.contentWindow.document.body.scrollHeight + addHeight + "px";
  }

You can retrieve the height of the IFRAME's content by using: contentWindow.document.body.scrollHeight

After the IFRAME is loaded, you can then change the height by doing the following:

<script type="text/javascript">
  function iframeLoaded() {
      var iFrameID = document.getElementById('idIframe');
      if(iFrameID) {
            // here you can make the height, I delete it first, then I make it again
            iFrameID.height = "";
            iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
      }   
  }
</script>   

Then, on the IFRAME tag, you hook up the handler like this:

<iframe id="idIframe" onload="iframeLoaded()" ...

I had a situation a while ago where I additionally needed to call iframeLoaded from the IFRAME itself after a form-submission occurred within. You can accomplish that by doing the following within the IFRAME's content scripts:

parent.iframeLoaded();

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to iframe

Getting all files in directory with ajax YouTube Autoplay not working Inserting the iframe into react component How to disable auto-play for local video in iframe iframe refuses to display iFrame onload JavaScript event YouTube iframe embed - full screen Change New Google Recaptcha (v2) Width load iframe in bootstrap modal Responsive iframe using Bootstrap