Adjusting the height of iframes to match the content across domains

Matthew Nuzum —  — 5 Comments

My current task will be assisted by showing an iframe but without the distinctive scrolling of an iframe. So if the iframe content is 350px high the iframe should be 350px high so that it appears to be part of the content above and below it. I’ve seen people refer to this technique as “100% height iframes” but I think that’s a misnomer or at least confusing since some people want an iframe that fills the height of its parent container. I just want an iframe that looks and acts as if its content were part of the normal page content and not on a separate site.

This isn’t so hard to do when your content is all on the same domain but when you need to work across domains its far more difficult because of the same domain security policies all browsers enforce. But there are ways to do it and the way I’m using now is clever and not well documented on the web. As a matter of fact, if it is documented I couldn’t find it. It does not require an iframe within an iframe nor does it require that the iframe’s content be tailored to the site that will be embedding the iframe. I’d love to hear any advice or suggestions for making it better.

In a nutshell, you simply have the iframe detect its referrer, which should be the parent frame, and then change the parent frame’s URL to add a hash/fragment which includes the height of the inner iframe’s content. A script on the outer frame watches for the hash to change and then once it does, gets the height and resizes the frame. Code is below.

The problem with this is that in firefox the back button needs to be clicked twice to go back after the iframe’s content loads. In IE this doesn’t happen and I’m not sure which browser is doing things wrong. However Google may be using a similar technique for their custom search feature because [they have the same problem](http://groups.google.com/group/google-custom-search-suggestions/browse_thread/thread/6d8fc7039900d903/01edc8ea586f9515). I seem to remember in olden days there was a way to remove items from the browser history… brief searching reveals no code though so I’m going to have to dig through some books to find out what I’m remembering (or mis-remembering maybe).

Remarkably, this is the exact opposite problem a lot of ajax applications are experiencing. I’m trying to remove items from the history and they try to add items. 🙂

Anyway, here’s the code, please please _please leave comments_ if you’re trying this. I’d really like to know if I’m on the right track.

__In the iframe, you need this:__ _(it uses mootools for the domready event but it could as easily be in the body’s onload event)_

window.addEvent(‘domready’, function() {
ref = document.referrer;
h = document.body.offsetHeight;
if( top != self && ! (ref.indexOf(‘#’) >= 0) ) {
// create a url like #h312-6789 where 312 is the height
top.location = ref+’#h’+h+’-‘+parseInt(Math.random()*1000);
}
});

__In the page that will embed the iframe you need this code:__ _(this does not use mootools)_

function checkFragment() {
h = document.location.href.indexOf(‘#h’);
l = document.location.href.length;
if( h > 0) {
u = document.location.href.substring(h+2,l);
// u will be like 312 or 312-123456 and we only want the 312
height = parseInt(u.split(‘-‘)[0]);
setFrameHeight(height);
clearInterval(frameint);
}
}

function setFrameHeight(height)
{
var frame = document.getElementById(“downloadframe”);
frame.height = height + 20; // there’s a bit of scroll without the 20
}

// our interval
var frameint = self.setInterval(‘checkFragment()’, 500);

In the first script you need to change the path to point to mootools or change it to use the body’s onload.

In the second script change the path in the iframe tag to point to the correct content then __also__ change the height of the iframe to be something reasonably close (but a little long) to what you expect the height to be. Its better to be too long than too short since people read the pages from top down. If the iframe starts out too small you get a weird glitch where it shows up with scrollbars at first and then the the content suddenly grows so that the scroll bars disappear causing the content to also widen and reflow slightly. Its not a big deal but if you start out too long then the change in height is almost imperceptible.

If it helped, please share!Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+

Matthew Nuzum

Posts Twitter Facebook

Web guy, big thinker, loves to talk and write. Front end web, mobile and UX developer for John Deere ISG. My projects: @dsmwebgeeks @tekrs @squaretap ✝
  • matt

    OK, I’ve done my research, I think I was imagining the past ability to remove items from the history. However, here’s a solution that decreases the chances of breaking the back button in the browser:

    __In the parent frame__: (instead of what’s shown above)

    </iframe>
    <script type="text/javascript">
    function checkFragment() {
    h = document.location.href.indexOf('#h');
    l = document.location.href.length;
    if( h > 0) {
    u = document.location.href.substring(h+2,l);
    // u will be like 312 or 312-123456 and we only want the 312
    height = parseInt(u.split('-')[0]);
    setFrameHeight(height);
    clearInterval(frameint);
    // fix for browsers whose navigation gets confused by this script
    if(history.length > his)
    history.go(-1)
    }
    }

    function setFrameHeight(height)
    {
    var frame = document.getElementById("downloadframe");
    frame.height = height + 20; // there's a bit of scroll without the 20
    }
    // used for fixing the history in ff
    his = history.length
    // our interval
    var frameint = self.setInterval('checkFragment()', 500);
    </script>

    Again, feedback is welcome.