64

Possible Duplicate:
Resizing an iframe based on content

I'm loading an iFrame and want the parent to automatically change the height based upon the height of the iFrame's content.

To simply things, all pages belong to the same domain, so I shouldn't run into cross-site scripting issues.

Community
  • 1
  • 1
Allan
  • 2,516
  • 5
  • 25
  • 22
  • here is the best solution - http://stackoverflow.com/questions/5867985/iframe-100-height – T.Todua Jun 27 '13 at 12:24
  • A more up to date answer, that gives a range of options - http://stackoverflow.com/questions/14334154/iframe-auto-adjust-height-as-content-changes – David Bradshaw Jun 09 '14 at 23:19
  • Not a duplicate because cross-site scripting is not an issue here and is in the other post. – frnhr May 20 '19 at 18:38

12 Answers12

37

On any other element, I would use the scrollHeight of the DOM object and set the height accordingly. I don't know if this would work on an iframe (because they're a bit kooky about everything) but it's certainly worth a try.

Edit: Having had a look around, the popular consensus is setting the height from within the iframe using the offsetHeight:

function setHeight() {
    parent.document.getElementById('the-iframe-id').style.height = document['body'].offsetHeight + 'px';
}

And attach that to run with the iframe-body's onLoad event.

uınbɐɥs
  • 6,800
  • 5
  • 24
  • 42
Oli
  • 215,718
  • 61
  • 207
  • 286
  • This isn't working for me. Just to be clear, should setHeight() be defined WITHIN THE IFRAME HTML? But the-iframe-id is the id of the iframe as defined within the main page html? – AP257 Oct 01 '10 at 19:50
  • 2
    Yeah, doesn't quite work in IE either... it just sizes to the browser height. – Entity Jun 23 '11 at 00:17
  • Adding an offset of +- 60 pixels isn't a bad idea to make sure a scrollbar isn't visible (different browsers). – thomasvdb Sep 26 '11 at 08:40
  • 1
    There is an error in the above code. `parent.document.getElementById('the-iframe-id').height` should be `parent.document.getElementById('the-iframe-id').style.height` instead. Note that `height` is a property of `style` property. – Susam Pal May 14 '12 at 11:33
  • @SusamPal: With style.height we must specify it's pixels. It should be: `parent.document.getElementById('the-iframe-id').style.height = document['body'].offsetHeight + 'px';` – Loris Dec 18 '12 at 15:55
  • This solution is not working, or maybe it is missing some important information. – Alex C Dec 18 '15 at 17:13
  • Tested on Firefox, Chrome, Opera its working !!! +1 – Akshay Hegde Jan 06 '16 at 11:13
  • When exactly should this code be run? If this is run before the images in the frame are loaded, then it obviously wouldn't be of the correct size once those images load. If we wait for all images to load, then it could take very long if there are pixel tracking images present inside the iframe. – Shivanshu Goyal Dec 17 '16 at 07:55
14

Try:

xmedeko
  • 5,855
  • 5
  • 44
  • 75
10

I just happened to come by your question and i have a solution. But its in jquery. Its too simple.

$('iframe').contents().find('body').css({"min-height": "100", "overflow" : "hidden"});
setInterval( "$('iframe').height($('iframe').contents().find('body').height() + 20)", 1 );

There you go!

Cheers! :)

Edit: If you have a Rich Text Editor based on the iframe method and not the div method and want it to expand every new line then this code will do the needful.

Shripad Krishna
  • 10,045
  • 4
  • 50
  • 63
8

Here is a dead simple solution that works on every browser and with cross domains:

First, this works on the concept that if the html page containing the iframe is set to a height of 100% and the iframe is styled using css to have a height of 100%, then css will automatically size everything to fit.

Here is the code:

<head>
<style type="text/css"> 
html {height:100%}
body {
margin:0;
height:100%;
overflow:hidden
}
</style>
</head>

<body>
<iframe allowtransparency=true frameborder=0 id=rf sandbox="allow-same-origin allow-forms allow-scripts" scrolling=auto src="http://www.externaldomain.com/" style="width:100%;height:100%"></iframe>
</body>
Sky
  • 185
  • 3
  • 7
  • Does that also work when the iframe is not a direct child of the body but, say, a div (on all browsers, that is)? – Aaron Digulla Aug 11 '10 at 07:22
  • Yes it does - just set the div's height and width using css and then put the iframe inside your div and voila there should only be one set of scrollbars (unless you set the div to be 100% of the height of the page). – Sky Aug 11 '10 at 23:26
  • 1
    nope, does not. FF 3.6 win xp – henrijs Feb 02 '11 at 21:35
  • nope, not working in chrome either. – willem Apr 24 '13 at 09:28
2

This solution worked best for me. It uses jQuery and the iframe's ".load" event.

craigmoliver
  • 6,282
  • 12
  • 48
  • 87
1

In IE 5.5+, you can use the contentWindow property:

iframe.height = iframe.contentWindow.document.scrollHeight;

In Netscape 6 (assuming firefox as well), contentDocument property:

iframe.height = iframe.contentDocument.scrollHeight
1

I found the solution by @ShripadK most helpful, but it does not work, if there is more than one iframe. My fix is:

function autoResizeIFrame() {
  $('iframe').height(
    function() {
      return $(this).contents().find('body').height() + 20;
    }
  )
}

$('iframe').contents().find('body').css(
  {"min-height": "100", "overflow" : "hidden"});

setTimeout(autoResizeIFrame, 2000);
setTimeout(autoResizeIFrame, 10000);
  • $('iframe').height($('iframe').contents().find('body').height() + 20) would set the height of every frame to the same value, namely the height of the content of the first frame. So I am using jquery's height() with a function instead of a value. That way the individual heights are calculated
  • + 20 is a hack to work around iframe scrollbar problems. The number must be bigger than the size of a scrollbar. The hack can probably be avoided but disabling the scrollbars for the iframe.
  • I use setTimeout instead of setInterval(..., 1) to reduce CPU load in my case
geekQ
  • 27,452
  • 11
  • 58
  • 53
1

My solution, (using jquery):

<iframe id="Iframe1" class="tabFrame" width="100%" height="100%" scrolling="no" src="http://samedomain" frameborder="0" >
</iframe>  
<script type="text/javascript">
    $(function () {

        $('.tabFrame').load(function () {
            var iframeContentWindow = this.contentWindow;
            var height = iframeContentWindow.$(document).height();
            this.style.height = height + 'px';
        });
    });
</script>
iknowitwasyoufredo
  • 575
  • 1
  • 9
  • 19
  • After small fix works for me: $('iframe').load(function() { var iframeContentWindow = this.contentWindow; var height = $(iframeContentWindow.document).height(); this.style.height = height + 'px'; }); – Mikhail May 12 '12 at 16:13
  • and a missing }); at the end also ;) – Ruslan Abuzant Aug 11 '12 at 01:19
0

Oli has a solution that will work for me. For the record, the page inside my iFrame is rendered by javascript, so I'll need an infinitesimal delay before reporting back the offsetHeight. It looks like something along these lines:


    $(document).ready(function(){
        setTimeout(setHeight);
    });

    function setHeight() {
        alert(document['body'].offsetHeight);   
    }
Allan
  • 2,516
  • 5
  • 25
  • 22
0

My workaround is to set the iframe the height/width well over any anticipated source page size in CSS & the background property to transparent.

In the iframe set allow-transparency to true and scrolling to no.

The only thing visible will be whatever source file you use. It works in IE8, Firefox 3, & Safari.

GDP
  • 7,641
  • 6
  • 40
  • 73
Gale
  • 9
  • 1
0

This is the easiest method i have found using prototype:

Main.html:

<html>
<head>


<script src="prototype.js"></script>

<script>
    function init() {
        var iframe = $(document.getElementById("iframe"));
        var iframe_content = $(iframe.contentWindow.document.getElementById("iframe_content"));
        var cy = iframe_content.getDimensions().height;
        iframe.style.height = cy + "px";
    }
</script>

</head>

<body onload="init()">


<iframe src="./content.html" id="iframe" frameBorder="0" scroll="no"></iframe>

<br>
this is the next line

</body>
</html>

content.html:

<html>
<head>
<script src="prototype.js"></script>


<style>
body {
    margin: 0px;
    padding: 0px;
}
</style>


</head>

<body>


<div id="iframe_content" style="max-height:200px;">
Sub content<br>
Sub content<br>
...
...
...
</div>


</body>
</html>

This seems to work (so far) in all the major browsers.

Ian Harrigan
  • 824
  • 6
  • 14
  • Misunderstood the question, fair enough. The code above will resize an iframe to its own content size though (may also be of use to someone) – Ian Harrigan Jul 23 '11 at 02:45
-1

Actually - Patrick's code sort of worked for me as well. The correct way to do it would be along the lines of this:

Note: there's a bit of jquery ahead:


if ($.browser.msie == false) {
    var h = (document.getElementById("iframeID").contentDocument.body.offsetHeight);
} else {
    var h = (document.getElementById("iframeID").Document.body.scrollHeight);
}
Allan
  • 2,516
  • 5
  • 25
  • 22