Adjusting the height of iframes to match the content across domains

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


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


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.

Comments
5 Responses to “Adjusting the height of iframes to match the content across domains”
  1. matt says:

    Joel, I’m sorry to say that this won’t work for you. There still needs to be a level of communication between both sites. However it is still better than some solutions because you only need two pages, the parent and the child frame (some solutions require a third page embedded in the child frame, hosted in the same domain as the parent).

    Still not a solution to Joel’s problem but another idea that may work and not have the nasty page-refresh problem in firefox is http://ajaxian.com/archives/whats-in-a-windowname

  2. Joel says:

    So… just so I’m clear — your addendum only modified step #2 of your original instructions, right? I’d still need to embed the mootools stuff within the document that will be appearing in the iframe?

    I initially thought your solution was the one i was looking for, but it doesn’t appear to be…

    I’m looking for a something that will work without having to attach anything to the pages that will be appearing within the frame. The site I administer will be featuring a few third-party solutions that we’d like to frame within our template. And I can’t modify those pages and add scripts to them.

    But I hate the scroll bars people inevitable have to wrestle with when these pages grow outside of the dedicated frame size. So… I’ll keep looking for options unless I’m not understanding correctly how to implement your solution.

    Thanks for your work, though. Looks like good stuff. And your site looks interesting, too. I love running into techy theologians like myself :)

  3. matt says:

    I’m not sure I understand what you mean. It does not create any new HTML, the top frame merely adjusts the height of the iframe to match what it was told by the javascript running in the iframe. The javascript communicates this information by changing the URL of the top frame, however that URL shouldn’t cause anything to actually happen since it’s only changing the hash fragment to something that wouldn’t normally exist.

  4. Tammy M Freeman says:

    Hello,

    Firstly, thank you so much for this script. I do have one question though. So when you script runs, it creates something like a new html instead of updating the page where the iframe is held. Is there anyway around that? I only ask because the whole reason Im using the iframe is to be able to center the page and bc it goes back to the source page, it is uncentered. Any help would be appreciated….thanks again!

  5. matt says:

    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.

Leave A Comment