Reputation: 95
Using some of the many examples that can be found easily via Google, I have written code to resize an iframe to fit its content(which is dynamically generated via php). It works, but with an issue that I cannot, despite many searches, find a solution to. First, here is the pertinent code:
Main HTML
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src=(JQuery URL)></script>
<script src=(External JS file URL, code detailed below)></script>
</head>
<body>
<div id="container">
<iframe id="iframe" src=(url of source file) onload="resize()"></iframe>
</div>
</body>
</html>
iFrame Source HTML
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="innerFrameDivs">
<?php (dynamically generated content) ?>
</div>
<div class="innerFrameDivs">
<?php (dynamically generated content) ?>
</div>
</body>
</html>
Javascript
function resize()
{
var iframe = document.getElementById("iframe");
var contentHeight = iframe.contentDocument.body.scrollHeight;
$('#iframe').css('height',contentHeight);
}
CSS
#iframe {
display:block;
border:none;
height:auto;
}
So with all of this, the iframe resizes to fit its content, except that it leaves a chunk of empty space below its contents.
I have figured out that this is because the scrollHeight being reported by the iframe is bigger than the height of its contents actually is, and of course if you set an element's height to something bigger than what's inside, there's going to be empty space at the bottom.
I investigated further and discovered that the iframe is reporting the actual individual heights of the elements within as being larger than they actually are as well. That is to say, I ran this JS on the page with the iframe:
$('#iframe').contents().find('.innerFrameDivs').each(function(){
var height = $(this).css('height');
alert(height);
});
and this JS on the iframe's source page opened natively in its own browser tab:
$(document).find('.innerFrameDivs').each(function(){
var height = $(this).css('height');
alert(height);
});
And despite the elements being the same, with the same css, different heights were reported. For example, in one instance, the iframe reported the top div's height as 241 and the bottom div's height as 901, while the iframe source page when opened natively in a browser tab reported the top div's height as 207 and the bottom div's height as 785.
So the iframe is inflating the heights of its interior elements, and thus its scrollHeight, for some reason, and I don't know why. I thought of just taking a percentage of the scrollHeight, say 90%, and using that as the iframe height, but since the content of the inner divs is generated dynamically, there will be dramatically varying heights, so that doesn't work very well.
I put the 'display:block' and 'height:auto' in the css for the iframe because I saw some suggestions in other discussions here that those rules could help in dealing with this issue, but they did nothing.
This issue is in all browsers, though it is more dramatic in Chrome and Safari than in Firefox(because webkit generally measures heights bigger than Mozilla).
Does anyone know what's causing this and/or how to fix it?
Upvotes: 3
Views: 559
Reputation: 95
So I figured it out. I had been setting the iframe's width to 100% in the JavaScript, but only after getting the element heights, so I neglected to realize that when those heights were retrieved, they were being retrieved from elements that had horizontal scrollbars on them, and that's where the extra height was coming from. Setting the iframe's width to 100% in the CSS rather than the JS solved the problem.
It's always something so obvious that keeps you banging your head on the wall for hours.
Upvotes: 1