I need a solution for auto-adjusting the width
and height
of an iframe
to barely fit its content. The point is that t
one-liner solution for embeds: starts with a min-size and increases to content size. no need for script tags.
<iframe src="http://URL_HERE.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>
If you can control both IFRAME content and parent window then you need the iFrame Resizer.
This library enables the automatic resizing of the height and width of both same and cross domain iFrames to fit their contained content. It provides a range of features to address the most common issues with using iFrames, these include:
In jQuery, this is the best option to me, that really help me!! I wait that help you!
iframe
<iframe src="" frameborder="0" id="iframe" width="100%"></iframe>
jQuery
<script>
var valueSize = $( "#iframe" ).offset();
var totalsize = (valueSize.top * 2) + valueSize.left;
$( "#iframe" ).height(totalsize);
</script>
All solutions given thus far only account for a once off resize. You mention you want to be able to resize the iFrame after the contents are modified. In order to do this, you need to execute a function inside the iFrame (once the contents are changed, you need to fire an event to say that the contents have changed).
I was stuck with this for a while, as code inside the iFrame seemed limited to the DOM inside the iFrame (and couldn't edit the iFrame), and code executed outside the iFrame was stuck with the DOM outside the iFrame (and couldn't pick up an event coming from inside the iFrame).
The solution came from discovering (via assistance from a colleague) that jQuery can be told what DOM to use. In this case, the DOM of the parent window.
As such, code such as this does what you need (when run inside the iFrame) :
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#IDofControlFiringResizeEvent").click(function () {
var frame = $('#IDofiframeInMainWindow', window.parent.document);
var height = jQuery("#IDofContainerInsideiFrame").height();
frame.height(height + 15);
});
});
</script>
I had to do this myself in a context of a web-extension. This web-extension injects some piece of UI into each page, and this UI lives inside an iframe
. The content inside the iframe
is dynamic, so I had to readjust the width and height of the iframe
itself.
I use React but the concept applies to every library.
Inside the iframe
I changed body
styles to have really big dimensions. This will allow the elements inside to lay out using all the necessary space. Making width
and height
100% didn't work for me (I guess because the iframe has a default width = 300px
and height = 150px
)
/* something like this */
body {
width: 99999px;
height: 99999px;
}
Then I injected all the iframe UI inside a div and gave it some styles
#ui-root {
display: 'inline-block';
}
After rendering my app inside this #ui-root
(in React I do this inside componentDidMount
) I compute the dimensions of this div like and sync them to the parent page using window.postMessage
:
let elRect = el.getBoundingClientRect()
window.parent.postMessage({
type: 'resize-iframe',
payload: {
width: elRect.width,
height: elRect.height
}
}, '*')
In the parent frame I do something like this:
window.addEventListener('message', (ev) => {
if(ev.data.type && ev.data.type === 'resize-iframe') {
iframe.style.width = ev.data.payload.width + 'px'
iframe.style.height = ev.data.payload.height + 'px'
}
}, false)
If you can live with a fixed aspect ratio and you would like a responsive iframe, this code will be useful to you. It's just CSS rules.
.iframe-container {
overflow: hidden;
/* Calculated from the aspect ration of the content (in case of 16:9 it is 9/16=
0.5625) */
padding-top: 56.25%;
position: relative;
}
.iframe-container iframe {
border: 0;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
The iframe must have a div as container.
<div class="iframe-container">
<iframe src="http://example.org"></iframe>
</div>
The source code is based on this site and Ben Marshall has a good explanation.