[html] How can I scale the content of an iframe?

How can I scale the content of an iframe (in my example it is an HTML page, and is not a popup) in a page of my web site?

For example, I want to display the content that appears in the iframe at 80% of the original size.

This question is related to html css dom

The answer is


If your html is styled with css, you can probably link different style sheets for different sizes.


I think you can do this by calculating the height and width you want with javascript (via document.body.clientWidth etc.) and then injecting the iframe into your HTML like this:

var element = document.getElementById("myid");
element.innerHTML += "<iframe src='http://www.google.com' height='200' width='" + document.body.clientWidth * 0.8 + "'/>";

I didn't test this in IE6 but it seems to work with the good ones :)


Kip's solution should work on Opera and Safari if you change the CSS to:

<style>
    #wrap { width: 600px; height: 390px; padding: 0; overflow: hidden; }
    #frame { width: 800px; height: 520px; border: 1px solid black; }
    #frame {
        -ms-zoom: 0.75;
        -moz-transform: scale(0.75);
        -moz-transform-origin: 0 0;
        -o-transform: scale(0.75);
        -o-transform-origin: 0 0;
        -webkit-transform: scale(0.75);
        -webkit-transform-origin: 0 0;
    }
</style>

You might also want to specify overflow: hidden on #frame to prevent scrollbars.


I just tested and for me, none of the other solutions worked. I simply tried this and it worked perfectly on Firefox and Chrome, just as I had expected:

<div class='wrap'>
    <iframe ...></iframe>
</div>

and the css:

.wrap {
    width: 640px;
    height: 480px;
    overflow: hidden;
}

iframe {
    width: 76.92% !important;
    height: 76.92% !important;
    -webkit-transform: scale(1.3);
    transform: scale(1.3);
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}

This scales all the content by 30%. The width/height percentages of course need to be adjusted accordingly (1/scale_factor).


You don't need to wrap the iframe with an additional tag. Just make sure you increase the width and height of the iframe by the same amount you scale down the iframe.

e.g. to scale the iframe content to 80% :

#frame { /* Example size! */
    height: 400px; /* original height */
    width: 100%; /* original width */
}
#frame {
    height: 500px; /* new height (400 * (1/0.8) ) */
    width: 125%; /* new width (100 * (1/0.8) )*/

    transform: scale(0.8); 
    transform-origin: 0 0;
}

Basically, to get the same size iframe you need to scale the dimensions.


I found a solution that works in IE and Firefox (at least on the current versions). On Safari/Chrome, the iframe is resized to 75% of its original size, but the content within the iframe is not scaled at all. In Opera, this doesn't seem to work. This feels a bit esoteric, so if there is a better way to do it I'd welcome suggestions.

<style>
#wrap { width: 600px; height: 390px; padding: 0; overflow: hidden; }
#frame { width: 800px; height: 520px; border: 1px solid black; }
#frame { zoom: 0.75; -moz-transform: scale(0.75); -moz-transform-origin: 0 0; }
</style>

...

<p>Some text before the frame</p>
<div id="wrap">
<iframe id="frame" src="test2.html"></iframe>
</div>
<p>Some text after the frame</p>
</body>

Note: I had to use the wrap element for Firefox. For some reason, in Firefox when you scale the object down by 75%, it still uses the original size of the image for layout reasons. (Try removing the div from the sample code above and you'll see what I mean.)

I found some of this from this question.


If you want the iframe and its contents to scale when the window resizes, you can set the following to the window's resize event as well as the iframes onload event.

function()
{
    var _wrapWidth=$('#wrap').width();
    var _frameWidth=$($('#frame')[0].contentDocument).width();

    if(!this.contentLoaded)
      this.initialWidth=_frameWidth;
    this.contentLoaded=true;
    var frame=$('#frame')[0];

    var percent=_wrapWidth/this.initialWidth;

    frame.style.width=100.0/percent+"%";
    frame.style.height=100.0/percent+"%";

    frame.style.zoom=percent;
    frame.style.webkitTransform='scale('+percent+')';
    frame.style.webkitTransformOrigin='top left';
    frame.style.MozTransform='scale('+percent+')';
    frame.style.MozTransformOrigin='top left';
    frame.style.oTransform='scale('+percent+')';
    frame.style.oTransformOrigin='top left';
  };

This will make the iframe and its content scale to 100% width of the wrap div (or whatever percent you want). As an added bonus, you don't have to set the css of the frame to hard coded values since they'll all be set dynamically, you'll just need to worry about how you want the wrap div to display.

I've tested this and it works on chrome, IE11, and firefox.


I do not think HTML has such functionality. The only thing I can imagine would do the trick is to do some server-side processing. Perhaps you could get an image snapshot of the webpage you want to serve, scale it on the server and serve it to the client. This would be a non-interactive page however. (maybe an imagemap could have the link, but still.)

Another idea would be to have a server-side component that would alter the HTML. SOrt of like the firefox 2.0 zoom feature. this of course is not perfect zooming, but is better than nothing.

Other than that, I am out of ideas.


This was my solution on a page with 890px width

#frame { 
overflow: hidden;
position: relative;
width:1044px;
height:1600px;
-ms-zoom: 0.85;
-moz-transform: scale(0.85);
-moz-transform-origin: 0px 0;
-o-transform: scale(0.85);
-o-transform-origin: 0 0;
-webkit-transform: scale(0.85);
-webkit-transform-origin: 0 0; 

}

The #wrap #frame solution works fine, as long as the numbers in #wrap is #frame times the scale factor. It shows only that part of the scaled down frame. You can see it here scaling down websites and putting it into a pinterest like form (with the woodmark jQuery plugin):

http://www.genautica.com/sandbox/woodmark-index.html


html{zoom:0.4;} ?-)


After struggling with this for hours trying to get it to work in IE8, 9, and 10 here's what worked for me.

This stripped-down CSS works in FF 26, Chrome 32, Opera 18, and IE9 -11 as of 1/7/2014:

.wrap
{
    width: 320px;
    height: 192px;
    padding: 0;
    overflow: hidden;
}

.frame
{
    width: 1280px;
    height: 786px;
    border: 0;

    -ms-transform: scale(0.25);
    -moz-transform: scale(0.25);
    -o-transform: scale(0.25);
    -webkit-transform: scale(0.25);
    transform: scale(0.25);

    -ms-transform-origin: 0 0;
    -moz-transform-origin: 0 0;
    -o-transform-origin: 0 0;
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}

For IE8, set the width/height to match the iframe, and add -ms-zoom to the .wrap container div:

.wrap
{
    width: 1280px; /* same size as frame */
    height: 768px;
    -ms-zoom: 0.25; /* for IE 8 ONLY */
}

Just use your favorite method for browser sniffing to conditionally include the appropriate CSS, see Is there a way to do browser specific conditional CSS inside a *.css file? for some ideas.

IE7 was a lost cause since -ms-zoom did not exist until IE8.

Here's the actual HTML I tested with:

<div class="wrap">
   <iframe class="frame" src="http://time.is"></iframe>
</div>
<div class="wrap">
    <iframe class="frame" src="http://apple.com"></iframe>
</div>

http://jsfiddle.net/esassaman/PnWFY/


As said, I doubt you can do it.
Maybe you can scale at least the text itself, by setting a style font-size: 80%;.
Untested, not sure it works, and won't resize boxes or images.


For those of you having trouble getting this to work in IE, it is helpful to use -ms-zoom as suggested below and use the zoom function on the #wrap div, not the iframe id. In my experience, with the zoom function trying to scale the iframe div of #frame, it would scale the iframe size and not the content within it (which is what you're going for).

Looks like this. Works for me on IE8, Chrome and FF.

#wrap {
  overflow: hidden;
  position: relative;
  width:800px;
  height:850px;
  -ms-zoom: 0.75;
}

Followup to lxs's answer: I noticed a problem where having both the zoom and --webkit-transform tags at the same time seems to confound Chrome (version 15.0.874.15) by doing a double-zoom sort of effect. I was able to work around the issue by replacing zoom with -ms-zoom (targeted only at IE), leaving Chrome to make use of just the --webkit-transform tag, and that cleared things up.


So probably not the best solution, but seems to work OK.

<IFRAME ID=myframe SRC=.... ></IFRAME>

<SCRIPT>
    window.onload = function(){document.getElementById('myframe').contentWindow.document.body.style = 'zoom:50%;';};
</SCRIPT>

Obviously not trying to fix the parent, just adding the "zoom:50%" style to the body of the child with a bit of javascript.

Maybe could set the style of the "HTML" element, but didn't try that.


Thought I'd share what I came up with, using much of what was given above. I haven't checked Chrome, but it works in IE, Firefox and Safari, so far as I can tell.

The specifics offsets and zoom factor in this example worked for shrinking and centering two websites in iframes for Facebook tabs (810px width).

The two sites used were a wordpress site and a ning network. I'm not very good with html, so this could probably have been done better, but the result seems good.

<style>
    #wrap { width: 1620px; height: 3500px; padding: 0; position:relative; left:-100px; top:0px; overflow: hidden; }
    #frame { width: 1620px; height: 3500px; position:relative; left:-65px; top:0px; }
    #frame { -ms-zoom: 0.7; -moz-transform: scale(0.7); -moz-transform-origin: 0px 0; -o-transform: scale(0.7); -o-transform-origin: 0 0; -webkit-transform: scale(0.7); -webkit-transform-origin: 0 0; }
</style>
<div id="wrap">
    <iframe id="frame" src="http://www.example.com"></iframe>
</div>

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to dom

How do you set the document title in React? How to find if element with specific id exists or not Cannot read property 'style' of undefined -- Uncaught Type Error adding text to an existing text element in javascript via DOM Violation Long running JavaScript task took xx ms How to get `DOM Element` in Angular 2? Angular2, what is the correct way to disable an anchor element? React.js: How to append a component on click? Detect click outside React component DOM element to corresponding vue.js component