Home   |   Products   |   Services   |   Support   |   Contact Us

Support

 

Dynamically Resized IFrames - Part 2: Fitting the Content

Summary

This article describes how to eliminate multiple scroll bars when using the IFrame tag, by dynamically resizing the IFrame to fit the content in the frame.

This article is part 2 in a series on how to eliminate "scroll bar hell" when using Iframes. Part 1 "Dynamically Resized IFrames - Part 1: Eliminating Multiple Scroll Bars" describes how to make the IFrame shrink or grow to fill the browser window, so you only get the "inner" IFrame scroll bar, eliminating the outer browser window scroll bar.

Background

See Part 1 of this series for the background information on how IFrames are useful but can lead to excessively complicated multiple scrolling regions on the user's screens.

Browser Compatibility

This solution has been tested in Internet Explorer 6.0.

Please send us feedback if you find it works (or does not work) in other browser brands and versions.

The Solution

Note - this solution will only work:

  • if you have control over the content of BOTH pages (the "outer" page with the IFRAME tag, and the "inner " page being displayed in the IFRAME)
  • if the outer and inner pages are being hosted on the same domain (and it's a little less work if they are on the same server)

The solution has two basic steps:

  • measure the height of the IFrame's content once the content has loaded
  • set the height of the IFrame to the height of the content

First, let's assume this is your IFrame tag:

<IFRAME
    src="http://myhost.mydomain.com/innerpage.html">

1. Set width = 100% and add an ID attribute to your IFrame

You should set WIDTH=100% - this normally has the desired effect.

Your IFrame must have an ID attribute that is unique across all HTML elements on the page. This makes the scripting easier later, and allows for having multiple IFrames on the page that all resize themselves.

Here is your modified IFrame:

<IFRAME ID="myiframe"
    src="http://myhost.mydomain.com/innerpage.html"
    width=100%>

2. Create a function to measure the height of the content, and set the IFrame height

To measure the height of the content, use the document.frames[] collection to access the IFrame's "inner" document.

If you use the document.all collection (or the IFrame ID object directly), you will be able to manipulate the IFrame tag itself - like set the height - but not access the inner content.

The JavaScript to get the height of the content is:

document.frames['myiframe'].document.body.scrollHeight;

The JavaScript to set the height of the IFrame is:

myiframe.height = <desired height>;

So the resulting JavaScript function to resize the IFrame looks like this:

<SCRIPT LANGUAGE="JavaScript">
function resizeIframeToFitContent(iframe) {
    // This function resizes an IFrame object
    // to fit its content.
    // The IFrame tag must have a unique ID attribute.
    iframe.height = document.frames[iframe.id]
                    .document.body.scrollHeight;
} </SCRIPT>

3. Set your initial IFrame height to 0

If the IFrame is bigger than its content, the scrollHeight attribute will return the height of the IFrame, not the "minimum" it needs for the content. So to make sure you are getting only the minimum height you need to show your content, set the IFRAME tag to HEIGHT=0 in your HTML.

<IFRAME ID="myiframe"
    src="http://myhost.mydomain.com/innerpage.html"
    width=100%
    height=0>

Like all HTML elements and attributes, this will only take effect when the page is initially loaded; scripts that modify this attribute later will permanently modify what it looks like on-screen; although a "View - Source" command will still show the original value.

4. Call the resize function when the content is loaded

IE has an "onload" event for the IFrame tag that we can use to call our resize function when the inner page has loaded (and the content height is known).

Add the onload event handler to your IFRAME tag:

<IFRAME ID="myiframe"
    src="http://myhost.mydomain.com/innerpage.html"
    width=100%
    height=0
    onload="resizeIframeToFitContent(this)">

The "this" object refers to the HTML element that holds the event handler, in this case it is a handle to the <IFRAME> tag itself.

Done! (maybe...)

Now test your page. You may find that the solution works now, and you need to go no further. But if you get a javascript error "Access Denied" (you may have to double-click a little yellow warning triangle in the bottom left corner of the IE window to see it) then you need to do the next step:

5. Browser Security Note

If your "inner" and "outer" pages are on different servers, both pages need to be modified to allow the browser scripts to execute.

Add this JavaScript to the top of BOTH pages:

<SCRIPT LANGUAGE="JavaScript">
document.domain = "mydomain.com";
</SCRIPT>

Replace "mydomain.com" with your actual domain name.

  • Both documents MUST be set to the same domain, or the security error will happen.
  • The domain you choose MUST be the same as the URL being used to access the page.
  • You must access the outer and inner pages with a fully qualified host name e.g. http://myhost.mydomain.com/..., not just http://myhost/...

This will tell the browser that both pages are coming from the same domain (which implies they are controlled by the same company and can be trusted) and hence scripts on one page can access the content (i.e. body.scrollHeight) of the other page.

Notes

This solution will not adjust the IFrame height if the page is resized; the IFrame height is only determined when the content is initially loaded. It also will not resize when only the IFrame content changes (e.g. by clicking a link in the inner page that reloads only the inner page).

I tried unsucessfully to get the onresize and onresizeend events to call my resize function; if anyone has success with this please send us feedback and we will post your solution (and give you credit).

Related Information (mostly MSDN)

Home | Products | Services | Support | Contact Us
Copyright © 2004, Wolf Creek Consulting. All rights reserved.