29

How is it possible to zoom out an entire document with JavaScript ?

My goal is to imitate the built-in browser zoom and zoom the entire document to 90%.

I have tried using

document.body.zoom

This works only with explorer and the page gets messy (a lot of elements are moving around).

Is there a way to do this?

Lix
  • 47,311
  • 12
  • 103
  • 131
lior r
  • 2,220
  • 7
  • 43
  • 80

6 Answers6

34

There you go:

Use:

document.body.style.zoom=1.0;this.blur();

1.0 means 100%

150% would be 1.5 1000% would be 10.0

this.blur() means that the curser, maybe you selected an input field, looses focus of every select item.

or:

You can use the css3 element zoom (Source)

Firefox does not allow zooming with the browser because you can't access the user properties via javascript or sth.

So you can just use some CSS styles which allow to zoom (CSS3: zoom, as mentioned above) or to increase the text size! Which you could do with including a different CSS file for example. But here you have the "jumpy" problem, because the styled css elements (floated etc.) have to "interact" different in fact of their attributes.

The zoom I posted above works well in Chrome and IE8+ (FF not supported as mentioned)

-- Additional information:

Here is an example on how to zoom exactly with the zoom option. Example application can be found here

The zoom option normally handles the zoom as your browser does!

But this is still all stuff, which is not supported by Firefox, or maybe Safari & Opera? In chrome and IE it works!

Another solution would be: Place your main sizes in "em", and then work around by setting sizes like 100%, 110% (all over the css). So you could have differen CSS files, and "just" need to replace the % attributes!

Yet I don't think there might be other solutions! :(

Community
  • 1
  • 1
creativeby
  • 859
  • 6
  • 10
  • Whilst this may theoretically answer the question, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Lix May 05 '12 at 17:33
  • thanks , while your solution does work it does not imitate the exact action caused by ctrl+ or ctrl-. the css zoom feature messes up some of the page structure (especially when dealing with margin:auto) while the ctrl+- does not ... is there any other way for doing this ? – lior r May 06 '12 at 20:49
  • Edited my post! I hope I understood what you want? :) (Still you have the issue that Firefox / Safari? / Opera? does not support zooming!) – creativeby May 06 '12 at 23:55
6

Here is my solution using CSS transform: scale() and JavaScript / jQuery:

jQuery(document).ready(function($) {
    // Set initial zoom level
    var zoom_level = 100;

    // Click events
    $('#zoom_in').click(function() {
        zoom_page(10, $(this))
    });
    $('#zoom_out').click(function() {
        zoom_page(-10, $(this))
    });
    $('#zoom_reset').click(function() {
        zoom_page(0, $(this))
    });

    // Zoom function
    function zoom_page(step, trigger) {
        // Zoom just to steps in or out
        if (zoom_level >= 120 && step > 0 || zoom_level <= 80 && step < 0) return;

        // Set / reset zoom
        if (step == 0) zoom_level = 100;
        else zoom_level = zoom_level + step;

        // Set page zoom via CSS
        $('body').css({
            transform: 'scale(' + (zoom_level / 100) + ')', // set zoom
            transformOrigin: '50% 0' // set transform scale base
        });

        // Adjust page to zoom width
        if (zoom_level > 100) $('body').css({
            width: (zoom_level * 1.2) + '%'
        });
        else $('body').css({
            width: '100%'
        });

        // Activate / deaktivate trigger (use CSS to make them look different)
        if (zoom_level >= 120 || zoom_level <= 80) trigger.addClass('disabled');
        else trigger.parents('ul').find('.disabled').removeClass('disabled');
        if (zoom_level != 100) $('#zoom_reset').removeClass('disabled');
        else $('#zoom_reset').addClass('disabled');
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!-- Trigger -->
<ul id="zoom_triggers">
    <li><a id="zoom_in">zoom in</a></li>
    <li><a id="zoom_out">zoom out</a></li>
    <li><a id="zoom_reset">reset zoom</a></li>
</ul>
Filip Š
  • 746
  • 2
  • 13
  • 22
Bogdanio
  • 489
  • 7
  • 8
  • This is great only thing is i want the page to zoom in and out but then refresh to take up the full screen like it does when you manually zoom using the browser. In this case for me it just zooms the body in and out to the size. I want the page to remain the same size but just increase or decrease the size of the items contained within it. – b3labs Feb 04 '16 at 13:40
5

Try using transform: scale(). Mozilla Docs

.className {
    transform: scale(0.9)
}

You can change the scale amount with Javascript.

let scaleAmount = 1 - 0.1
document.body.style.transform = `scale(${scaleAmount})`

scale() reduces or increases the width and height of an element. If you'd like the width to remain the original size, while all inner elements scale, the algorithm looks something like this:

let scaleAmount = 1 - 0.1
document.body.style.transform = `scale(${scaleAmount})`
document.body.style.width = `${100 * (1 / scaleAmount)}%`
document.body.style['transform-origin'] = `0 0`

If you use a UI framework like React, you can pass the scaleAmount as it exists in the state to inline CSS.

<header className="App-header" style ={{
    transform: `scale(${scaleState})`,
    transformOrigin: '0 0',
    width: `${100 * (1 / scaleState)}%`
}}>

Example in React

Edson A
  • 53
  • 1
  • 5
2

I did this with jquery, works with Firefox, Safari, Chrome and IE9+:

window.onload = function() {
  var currFFZoom = 1;
  var currIEZoom = 100;

  $('#In').on('click', function() {
    if (navigator.userAgent.indexOf('Firefox') != -1 && parseFloat(navigator.userAgent.substring(navigator.userAgent.indexOf('Firefox') + 8)) >= 3.6) { //Firefox
      var step = 0.02;
      currFFZoom += step;
      $('body').css('MozTransform', 'scale(' + currFFZoom + ')');
    } else {
      var step = 2;
      currIEZoom += step;
      $('body').css('zoom', ' ' + currIEZoom + '%');
    }
  });

  $('#Out').on('click', function() {
    if (navigator.userAgent.indexOf('Firefox') != -1 && parseFloat(navigator.userAgent.substring(navigator.userAgent.indexOf('Firefox') + 8)) >= 3.6) { //Firefox
      var step = 0.02;
      currFFZoom -= step;
      $('body').css('MozTransform', 'scale(' + currFFZoom + ')');

    } else {
      var step = 2;
      currIEZoom -= step;
      $('body').css('zoom', ' ' + currIEZoom + '%');
    }
  });
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="button" id="Out" value="Zoom Out"/>
<input type="button" id="In" value="Zoom In"/>
Filip Š
  • 746
  • 2
  • 13
  • 22
1

You can do the following thing:

document.body.style.zoom = "120%"
0

you have to set the zoom property in style for top level element (html). Now interesting part is how to calculate it. This is what I did. You can put this code inside window.onresize function to make the whole page zoom automatically.

window.onresize = function(){
    let zoom = Number((window.innerWidth / window.screen.width).toFixed(3));
    document.firstElementChild.style.zoom = zoom;
  }

This will calculate the ratio of current window width to actual device width.

Then set that value to top level html element zoom property. Top level html element can be accessed using document.firstElementChild

set the height of main wrapper div to 100% to prevent white space on zoom.

Ronn Wilder
  • 1,228
  • 9
  • 13