Is Google Chrome on Windows having problems to render iframe scrollbars?
I wrote a very simple code to show what is happening (at least with me on chrome 52.0.2743.82 m):
<button>Toggle visibility</button>
<br />
<iframe scrolling="yes" seamless src="https://en.wikipedia.org/wiki/Lorem_ipsum" frameborder="0" style="width: 700px; height: 300px"></iframe>
<script type="text/javascript">
$("button").on("click", function() {
$("iframe").toggle();
});
</script>
Plunker link to code
When the page is loaded, the iframe as it scrollbar are visible.
Hide and show the iframe clicking the button. The scrollbar disappears.
This issue apparently occurs only in chrome.
Anyone is experiencing this too? Any fixes/workarounds?
Open a Chrome window. In the address bar, enter "chrome://flags," and navigate to that page. Scroll down to Overlay Scrollbars, and set the field to "Disabled."
Remove Extensions Enabled extensions can also cause the Chrome vertical scroll bar missing problem. You can disable all extensions and then reboot Chrome. If the vertical scroll bar is back, the vertical scroll bar disappears because of one or some extensions.
Go to Settings / Ease of Access / Display and turn off Automatically hide scroll bars in Windows.
It seems that bug appeared with the update Chrome 52.0.2743.82 (http://googlechromereleases.blogspot.fr/2016/07/stable-channel-update.html)
One possible workaround is to use the attribute visibility
with position: absolute
instead of display
to show or hide the iframe
.
A chrome bug ticket exists for this item: https://bugs.chromium.org/p/chromium/issues/detail?id=641881
I've had this problem, and using visibility
instead of display: none
wasn't an option.
My workaround was to set overflow: scroll
on the <body>
of the document being displayed in the iframe, whenever I set the iframe to be visible again. This seems to force the scrollbar to appear on the iframe again. You can then reset the overflow
to its old value, and the scrollbar will remain on the iframe. You need to wait for a repaint before you can reset the overflow
, though, so I put this in a timeout with delay 0.
function showIframe(iframe) {
var iframeBody = iframe.contentDocument.body;
$(iframe).show();
var oldOverflow = iframeBody.css("overflow");
iframeBody.css("overflow", "scroll");
window.setTimeout(function () {
iframeBody.css("overflow", oldOverflow);
}, 0);
}
There is a "flash" of scrollbar with this workaround if the iframe in question doesn't need to scroll, though, so it might be worth using the visibility
workaround for that brief moment where the repaint is required, to avoid the flash.
Here's a workaround I've developed for an application I'm building. It has multiple <iframe>
elements in a Foundation tab-control.
I used MutationObserver
to observe when the <iframe>
's parent element (a Foundation div.tabs-content div.content
element) becomes active
, then I toggle the iframe
's document's overflow
property. The runtime effect is imperceivable.
I originally wanted to observe
the <iframe>
directly, however no DOM mutation events were raised when the iframe itself's changed display
property, I guess because technically speaking element.style
values are not part of the DOM-structure proper.
Here's my code (Vanilla.js, no jQuery). If you're using in your application you will want to replace my visibility-detection code with something that is applicable to your document:
window.addEventListener('DOMContentLoaded', function(e) {
var observer = new MutationObserver( onContentMutated );
var options = { attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ['class'] };
var iframeContainers = document.querySelectorAll('.tabs-content .content');
for(var i = 0; i < iframeContainers.length; i++) {
observer.observe( iframeContainers[i], options );
}
});
function onContentMutated(mutations) {
for(var i = 0; i < mutations.length; i++) {
var m = mutations[i];
var thisIsNowAnActiveTab = m.target.classList.contains('active');
if( thisIsNowAnActiveTab ) {
// get the corresponding iframe and fiddle with its DOM
var iframes = m.target.getElementsByTagName("iframe");
if( iframes.length == 0 ) continue;
var iframe = iframes[0];
iframe.contentWindow.document.documentElement.style.overflow = 'hidden';
// the timeout is to trigger Chrome to recompute the necessity of the scrollbars, which makes them visible again. Because the timeout period is 0 there should be no visible change to users.
setTimeout( function(s) {
s.overflow = 'auto';
}, 0, iframe.contentWindow.document.documentElement.style );
}
console.log( m.type );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With