I recently needed to host an iframe with dynamic content and keep the iframe height at 100% of the content height. I decided to create a solution using
window.postMessage to facilitate cross-domain communication. If you are unfamiliar with
postMessage, check out the documentation before proceeding.
Anyway, my approach looks like this:
- Parent window listens for messages that child iframe has updated height. Whenever it gets a message, it changes the height of the iframe.
- Parent window waits for child iframe to load and sends it a message.
- iframe receives message and establishes two-way communication.
- iframe sends message to parent window with initial height.
- When iframe content height changes, it sends message back to parent window with updated height.
Let’s get started with the iframe itself. I kept it simple for the purposes of my demo and created an iframe that performs the important task of adding a picture of a kitten to the page when the user clicks a button. My HTML is very basic:
I made the width of that cats div 300px wide:
As you can see, our iframe is waiting for a message. When it receives the message is shows some data to the user and prepares for two-way communication between itself and the parent window. You can view the iframe raw here and I also created a Pen if you prefer.
The Parent Window
In this case, we are housing the iframe on this blog post. Here is my iframe tag:
Putting It All Together
Both of these frames have an initial height of “100”. Here is the frame without using
postMessage to keep the height in sync. Go ahead and click “Make this page more awesome!” a few times and see what happens:
As you can see, we get scrollbars and it makes it extremely difficult to properly enjoy all of those glorious kittens. The user suddenly realizes that your site is using iframes and they grow suspicious that you are going to have a
prompt() for their name so you can greet them and they exit your site as quickly as possible. Now, let’s try that with our
postMessage approach to keep the height in sync with the content:
Tentative estimates place this user experience at about a 100% improvement.
Hopefully you don’t have to worry about cross-domain iframes that change height on you in your day-to-day life. If you do, consider this approach. It is easy to implement and has pretty good browser support.
Have you solved this problem using a different approach? Are there egregious errors in my post? Let me know!