If you’ve ever embedded an external page or app in your site using an <iframe>, you’ve probably faced this: the content inside is longer than the frame, and a scrollbar appears. Or worse, the frame cuts off content entirely. Ideally, your iframe should automatically resize based on the height of its contents — without scrollbars and without manual pixel adjustments.
Let’s fix that cleanly.
So, why doesn’t the iframe resize automatically?
By default, an <iframe> doesn’t know how tall its inner content is. The browser treats it as an isolated document (a separate DOM), so parent and child pages can’t directly access each other’s content height due to same-origin restrictions.
If both pages are under the same domain (same-origin), it’s simple. But if you’re embedding content from another site (like YouTube or a form hosted elsewhere), you’ll need an extra step using postMessage().
Case 1: Same-origin iframe (simplest)
If your iframe content is hosted on the same domain, you can directly access the child document and adjust the height.
Parent Page (main.html):
<iframe id="myIframe" src="/child.html" width="100%" frameborder="0"></iframe>
<script>
const iframe = document.getElementById('myIframe');
iframe.addEventListener('load', function() {
// Access the iframe document and adjust height
iframe.style.height = iframe.contentWindow.document.body.scrollHeight + 'px';
});
</script>
HTMLHow it works:
When the iframe finishes loading, we access its internal document (iframe.contentWindow.document) and set the iframe height equal to the child’s scrollHeight. The key is that both documents must be same-origin (i.e., served from the same domain, protocol, and port).
Case 2: Cross-origin iframe (different domain)
If your iframe content comes from another domain, you can’t directly read its height for security reasons. The fix? Use window.postMessage() — a safe way to send messages between windows.
You’ll need to make small adjustments on both the parent and child pages.
1. Child Page (the iframe content)
Add a script that sends its height to the parent window:
<script>
function sendHeight() {
const height = document.body.scrollHeight;
window.parent.postMessage({ frameHeight: height }, '*');
}
window.addEventListener('load', sendHeight);
window.addEventListener('resize', sendHeight);
</script>
JavaScriptThis code sends a message to the parent page with the current height of the iframe content. You can trigger it on load and whenever the content resizes.
2. Parent Page (where iframe is embedded)
Now, listen for that message and adjust the iframe height dynamically:
<iframe id="externalFrame" src="https://example.com/child" width="100%" frameborder="0"></iframe>
<script>
const iframe = document.getElementById('externalFrame');
window.addEventListener('message', (event) => {
// Optionally, verify event.origin for security
if (event.data && event.data.frameHeight) {
iframe.style.height = event.data.frameHeight + 'px';
}
});
</script>
HTMLWhy this works:
- The child safely communicates with the parent without direct DOM access.
- You can filter messages by checking
event.originif you want extra security. - The height updates in real-time whenever the iframe content changes size.
Bonus: Adjusting for dynamic content inside iframe
If the iframe content changes dynamically (e.g., form expands, tabs open), you can:
- Continuously send the height every few seconds.
- Or, use a
MutationObserverin the child page to send updates when the DOM changes:
const observer = new MutationObserver(sendHeight);
observer.observe(document.body, { childList: true, subtree: true });
This keeps the iframe perfectly fitted without the need for scrollbars — no matter how the content evolves.
Final thoughts
If you control both parent and child pages, the same-origin approach is simplest and most reliable. But for embedded apps, forms, or dashboards from other domains, the postMessage() approach is the go-to pattern used by platforms like Stripe, Typeform, and even embedded Google Maps.
Either way, the goal remains the same: let the iframe breathe. Avoid scrollbars. And make it feel like a native part of your page — not a boxed element.
Frequently Asked Questions
Can I resize an iframe automatically without JavaScript?
No, you can’t. CSS alone can’t access the content height of an iframe. JavaScript is required to measure or communicate the content’s dimensions.
What happens if the iframe source is from a completely different domain (like YouTube)?
You can’t directly access its DOM for security reasons. You’ll need to rely on the external site’s API or use postMessage() if they support it.
Does postMessage() work for all browsers?
Yes. It’s supported across all modern browsers, including Chrome, Firefox, Safari, and Edge. It’s the safest cross-origin communication method.
Can I use jQuery for iframe auto-resizing?
Yes, there are plugins like jquery-iframe-auto-height that simplify this logic. But the underlying mechanism is the same — reading the child’s height and setting it on the parent.
Is it safe to use ‘*’ in window.postMessage()?
Technically yes, but it’s better to restrict messages using the target domain. Instead of '*', use something like 'https://yourdomain.com' for improved security.