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

JavascriptJqueryasp.netIframe

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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();

Solution 2 - Javascript

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);

Solution 3 - Javascript

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();">

Solution 4 - Javascript

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());"

Solution 5 - Javascript

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');
}

Solution 6 - Javascript

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

Solution 7 - Javascript

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' );
});

Solution 8 - Javascript

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.

Solution 9 - Javascript

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' );

Solution 10 - Javascript

You can refer related question here - https://stackoverflow.com/questions/18765762/how-to-make-width-and-height-of-iframe-same-as-its-parent-div/38917939#38917939

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

Solution 11 - Javascript

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

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

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

Solution 12 - Javascript

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.

Solution 13 - Javascript

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>

Solution 14 - Javascript

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' );
    }
});

Solution 15 - Javascript

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";
  }

Solution 16 - Javascript

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%;
}

Solution 17 - Javascript

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%;   
}

Solution 18 - Javascript

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.

Solution 19 - Javascript

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);
});

Solution 20 - Javascript

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>';

Solution 21 - Javascript

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

and / or

$(window).height()

See Stack Overflow question https://stackoverflow.com/questions/806402.

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.

Solution 22 - Javascript

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkarryView Question on Stackoverflow
Solution 1 - JavascriptAristosView Answer on Stackoverflow
Solution 2 - JavascriptBlueFishView Answer on Stackoverflow
Solution 3 - JavascriptMarty MulliganView Answer on Stackoverflow
Solution 4 - JavascriptMohit AnejaView Answer on Stackoverflow
Solution 5 - JavascriptDavid BradshawView Answer on Stackoverflow
Solution 6 - JavascriptmbehzadView Answer on Stackoverflow
Solution 7 - JavascriptRaviView Answer on Stackoverflow
Solution 8 - Javascriptuser8640976View Answer on Stackoverflow
Solution 9 - JavascriptsreeView Answer on Stackoverflow
Solution 10 - JavascriptMohan DereView Answer on Stackoverflow
Solution 11 - JavascriptBinodView Answer on Stackoverflow
Solution 12 - JavascriptNisar AhmedView Answer on Stackoverflow
Solution 13 - JavascriptSunil Kumar SumanView Answer on Stackoverflow
Solution 14 - JavascriptMartin LesterView Answer on Stackoverflow
Solution 15 - JavascriptMatt StaceyView Answer on Stackoverflow
Solution 16 - JavascriptJuan MView Answer on Stackoverflow
Solution 17 - JavascriptloekView Answer on Stackoverflow
Solution 18 - JavascriptTadej VengustView Answer on Stackoverflow
Solution 19 - JavascriptKeyur SavsaniView Answer on Stackoverflow
Solution 20 - JavascriptjteksView Answer on Stackoverflow
Solution 21 - JavascriptMichael L WatsonView Answer on Stackoverflow
Solution 22 - JavascriptHatem BadawiView Answer on Stackoverflow