Avoid iframe-scrollbars with squeezeFrame.js

I know, this seems to have become an obsession of mine, but here I am again with a follow-up on my iframes-tips blogpost. You might remember I advised against disabling scrollbars on iframes, because;

Disabling them will render the iframe partially inaccessible for some of your users, because the size your iframe-content needs, depends on things outside your control such as operating system & versions (e.g. font & screen resolution), browser (e.g. css-implementation) and browser configuration (e.g. non-default font-size).

But what if you could resize (generally: zoom out) the iframe-content to perfectly fit the available width and height, thus avoiding vertical and especially horizontal scrollbars? Well, that is exactly what squeezeFrame.js tries to do (using css zoom and -moz-transform:scale in Firefox)! Just include the javascript-file in the iframe-content page and set a few options if you want to change the default behavior (which is: zoom in/out for width only, max. + or – 5%).
squeezeFrame.js was tested successfully in Firefox 3.6, IE6, Safari4 and Chrome4, but does not work in Opera 10.5. More info (including some “known issues”) can be found on the demo-page and in the javascript-code off course.
As always; reply in the comments or contact me if you find bugs or have problems.

25 thoughts on “Avoid iframe-scrollbars with squeezeFrame.js”

  1. It’s a <= IE8 bug I think. The issue might be when referencing external sites.
    Check it out here:
    kvp.net/iFrame.html <— site with the iframe
    corian123.net/iframe.html <—- redirects you to here^^

    Reply
    • don’t have access to a PC with IE<9 right now, but let me describe what is supposed to happen:
      1. when going to kvp.net/iFrame.html, you should stay on that page which contains the iframe with http://www.corian123.net/iframe.html inside it
      2. when going to kvp.net/sitemockup.html, you’re should stay on that page which contains the same iframed http://www.corian123.net/iframe.html
      3. when going to corian123.net/iframe.html (the page which is supposed to be in an iframe, you will indeed to be redirected to http://kvp.net/sitemockup.html
      the reason for the redirect is in the code of squeezeFrame (and can easily be changed):
      1. in iframe.html you have myContainer="http://www.kvp.net/sitemockup.html";
      2. in squeezeFrame.js there is: if (self !== top) { ... } else {
      if (typeof myContainer==="string") { window.location=myContainer; }
      }

      so if you don’t like the redirect, you could leave “myContainer” empty, or put the line in the “else”-block in comment.
      hope this helps!

      Reply
  2. Yeah baby!!!! I got it! I’m amazing!
    Ok, so the squeeze thing wasn’t working for me, and this way is far from foolproof, but…
    Use CSS3 Transforms, Scale! Beautiful!
    So I make the iFrame approx 120%, or whatever will fully encapsulate the entire site. Then, make the whole iFrame scaled. So add it to a class with this:
    -moz-transform: scale(.7);
    -webkit-transform: scale(.7);
    -o-transform: scale(.7);
    -ms-transform: scale(.7);
    transform: scale(.7);
    You can use anywhere from .5 to 2.0
    Fun fun! Ok, so I just got it working 20s ago, so I’m sure there’s lots of quirks to work out, but it sure is a start! Whoopee!

    Reply
    • great, keep me posted on your progress!
      (squeezeFrame.js uses -moz-transform:scale as well (as it didn’t do “zoom”), I found that I also had to declare -moz-transform-origin: 0 0; to make this work, might come in handy for you as well)

      Reply
      • I was working with the wordpress plugin wp pretty photo – absolutely amazing btw, as it supports images, vids, all media, iframes, and any html code. Love it.
        Anyway I got it working great in Firefox. Chrome required me to add that css to the actual site, which fortunately I did have control over. I think it was just a quirk with wp pretty photo and how I was working it all. Anyway, I decided putting the featured template/site in an iframe wasn’t worth the effort at the moment as there are far more pressing matters.
        I think it’s very doable, I just wasn’t up for tweaking it on each browser and didn’t have time.
        The only final adjustment would be to detect the user’s browser, and if it supports zooming. Depending on whether the zoom is for aesthetics or function, the appropriate actions, if any, would need to be taken. But of course you know all that.
        If I ever come back to it, I’ll let you know.
        Cheers!

        Reply
  3. Hi!
    Ok… If i have an iframe that shows another website that i have no control over. What would the code look like then? I have treid a million differnt ways but i cant get it to work. Maybe i´m an idiot….
    Cheers!

    Reply
  4. Hi Frank! Great piece of scripting! I have been looking for a solution like this for several years now. I use it to rescale my web site on my iFrame Facebook fan page. So I have http://www.mysite.com on full size, and on http://www.facebook.com/myPage I have a fanpge app that loads the http://www.mysite.com/container-page.htm (which loads the index.htm page). REsult on FB is a 810 px page ;o) .
    One caveat however. All underlying pages have different hights. Main page has more content and pictures as f.ex. page2.htm. So the hight is dynamic. Using a fixed definition like :
    is giving me a messy page end with lots of space on pages with less content. Using less is forcing me to use scrollbars, what I don’t like. And for every new page I create, I need to check if it will fit in the 4000 px. If not I need to modify that parameter. I have been looking at 2 or 3 scripts that do dynamic iFrame hights, but I can not get it working combined with your script.
    Any suggestions? By the way, I use “both” to avoid any form of scrollbar.

    Reply
    • Something I forgot to ask. It looks like if the line :
      myContainer=”container-page.htm”;
      is used to redirect all users that load the actual content page to the container-page, to make sure it is resized. I have commented this line out, so that users on http://www.mysite.com get the full size page, and visitors from facebook.com/myFanPage get the resized version. Is this a correct assumtion?

      Reply
    • I think the best approach would be to not use “both” but only (the default) “width”. This will allow for a much more consistent UI across pages, but will indeed allow vertical scrollbars (but only if needed).

      Reply
      • Hello Frank. I tried it with “width”, but then it looks like it is not zooming out. I use Chrome btw. In container-page.htm I had height everything from “1000” up to “4000”, and in content.htm used “width” and myMax varying from 0.10 up to 0.90. Result was that either way the text over the width always was to wide, resulting in a scroll bar in the bottom.
        Looks like only “both” + myMax 0.25 is doing the trick for me.
        You can see it live at:
        http://care4u.co.nf/container-page.htm and
        https://www.facebook.com/Care4U.hypnoterapi.EFT/app_197936773558886
        The odd thing is that when I lower the height to 2900 or below (or something like that…) the zoom out function is not working anymore. Only if I define sufficient space (like 810 x 4000) the zoom out fuction will work.
        Any idea on why that is? As you mentioned, if dynamic height is not possible, it would be great to have 810 width (no scroll), and 1000 px height with scroll. Great if you could help me figure this out ;o)

        Reply
        • Just had a look, no idea really. For reasons I don’t understand the zoom-factor cannot be calculated correctly. Might have to do with some other scripts doing things with the DOM.
          2 small remarks;
          1. there’s a space missing between your frameborder and width;
          <iframe src="index.htm" frameborder="0"width="805" height="2095"></iframe>
          2. the FB page remained blank for me I’m afraid, but that might be due to my browser settings (3rd party cookies, noscript, adblock, …).

          Reply
  5. Hey Frank,
    I’m puzzled… First it worked, then I made some changes and the zoom out stopped working. Restored all, but still no go … :o(.
    But here is the thing: I see the script creates a modified body tag that holds the zoom factor. So I was looking for a way to do following:
    if (document.referrer = “http://www.myWebSite.com/containerPage.html”)
    else
    Can this be done? Not sure what effect it will have on “notebook” displays, or 15″ vs 21″ monitors, but it could be interesting to see if I can bypass the problem of your script not wanting to zoom out. I tried it with the fixed body tag, and that is working fine. So now all I need to do is to make it referrer dependent. I’m not much of a java scripter, so I was hoping you could help me out on this one :o).
    Regards from sunny Norway!

    Reply
    • hmm, looks like the code between “” is chopped off …
      if (document.referrer = “http://www.myWebSite.com/containerPage.html”)
      body id=”page1″ style”zoom:0.75; -moz-transform: scale(0.75); -moz-transform-origin: 0 0;”
      else
      body

      Reply
      • That would probably work, but in that case the zoom-value is hardcoded, which e.g. for a responsive site might not always make sense (as you’d want your iframe and the page within that iframe to adapt to the available screen width)? But if you’re not in a responsive context and you see that you indeed need 75%, then the above idea (adding the style element to the body tag if referrer is your “container page”) should indeed work.

        Reply
  6. Hey Frank!
    Sorry I know this is an ancient post – so if there is now a much better way of doing this then please let me know!
    I wanted to get the ‘zoomed out’ version in my iframe which I think this will achieve (bear with me, I’m from a non-dev background).
    I’m running a wordpress site (http://theinsiders.org.uk/) so where do I upload the
    I’ve tried using the http://wordpress.org/plugins/superslider-perpost-code/ so I have the optional box on the post to add in the JS. I’ve copy and pasted in the text (example below) into the box, but then where do I actually put the code?
    Is that also in the same box or in the usual ‘html’ (rather than visual) blog post box? And does this have to be within the tags or before hand?
    Apologies if this is a super easy question!
    Thanks again!
    Mahdi
    Example of what’s in the Custom JS Box (enabled by the super slider plugin)
    —-
    // squeezeFrame.js; standalone JS to solve small rendering issues that cause
    // content to be inaccessible or scrollbars to appear on iframes
    //
    // version: 201003221700
    //
    // author: frank -futtta- goossens
    // License: CreativeCommons Attribution-Share Alike
    // (http://creativecommons.org/licenses/by-sa/3.0/) or
    // GNU LGPL (http://www.gnu.org/licenses/lgpl-3.0.txt)
    // more info: http://blog.futtta.be/2010/03/24/
    //
    // usage:
    // * include this script in the head of the iframe-content (i.e. in the
    // page that is displayed inside the iframe)
    // * set “myContainer” to the URL of the iframe container page (i.e. the
    // page in which the iframe is created/ defined), to redirect users
    // accessing the iframe-content out of context
    // * optionally set “myMax” with the maximum positive/negative zoom
    // allowed, e.g. 0.25 means that the page can zoom between 75 to 125%,
    // default is 0.10, so 90->110%
    // * optionally set “myRedraw” to “both” (default is “width”) to adjust
    // to both width and height
    //
    // example code:
    //
    //
    // myContainer=”http://url.to/container-page/”;
    // myMax=0.25;
    // myRedraw=”width”;
    //
    //
    // bugs & issues:
    // * embedded YouTube in Firefox becomes invisible (but Vimeo for example
    // does work)
    // * the vertical scrollbar does not always disappear in FF
    // * does not work in Opera
    window.onload=function() {
    if (self !== top) {
    if (typeof myMax!==”number”) { max=0.1; } else { max=myMax;}
    if (typeof myRedraw!==”string”) myRedraw=”width”;
    b=document.getElementsByTagName(‘body’)[0];
    zW=(b.clientWidth-5)/b.scrollWidth;
    if (myRedraw===”both”) {
    zH=(b.clientHeight)/b.scrollHeight;
    if (zH<zW && zH 1+max) { z=1+max; } else if (z<1-max) { z=1-max; }
    s="zoom:"+z+"; -moz-transform: scale("+z+"); -moz-transform-origin: 0 0;";
    if (typeof b.setAttribute === "function") b.setAttribute('style', s);
    else if (typeof b.style.setAttribute === "object") b.style.setAttribute('cssText', s);
    } else {
    if (typeof myContainer==="string") { window.location=myContainer; }
    }
    }

    Reply
    • Morning Mahdi;
      You would have to upload squeezeFrame.js to your WordPress-installation (using e.g. FTP or the WordPress Media Manager). In the superslider-perpost-code JS box you would then add;

      // load squeezeframe.js
      var sFr = document.createElement("script");
      sFr.src = "/wp-content/uploads/2013/11/squeezeFrame.js";
      document.body.appendChild(element);
      // configure squeezeFrame settings
      myMax=0.25;
      myRedraw="both";

      The line with the URL to squeezeFrame.js might need changes, depending on how & where the file got uploaded.
      Hope this helps (and works 😉 )
      frank

      Reply
  7. Awesome script, thanks Frank works like a dream , have at last been able to squeeze my wider store page into my narrower website iframe. Been trying to do this for a while
    Had to tweak it a little
    – blank the url of MyContainer
    – remove min width attributes in the source page .css
    I also noticed no vertical scroll bars visible for iOS , not a major problem

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.