164

I have need to create 2 buttons on my site that would change the browser zoom level (+) (-). I'm requesting browser zoom and not css zoom because of image size and layout issues.

Well, is this even possible? I've heard conflicting reports.

7
  • 15
    Browser zoom is something that should only be controlled by the user - never the web site. If the web site can alter the browser zoom level, that breaks the most basic accessibility feature that browsers have. I would consider any method of allowing a web site to change the browser zoom to be a serious bug, because any use of that feature would be abuse. Commented Jun 28, 2009 at 17:53
  • 49
    @unknown (google), nonsense. You're just very wrong. Such controls are invaluable for creating rich web applications in javascript that can measure up to flash, and secondly browsers can limit the zoom controls to be available only with user interaction and not give full control. Commented Jun 28, 2009 at 17:56
  • 161
    I really get tired of the whole "you should never XYZ". Yeah, that's all well and good in a perfect world, or when you're writing a brand-new site. But if the site is a decade old, the client won't pay for a new design, and your bosses expect you to make a site work on a tablet, that sort of "you really shouldn't" mentality can take a serious back-seat. If you know how to do something, say so. If you don't, then don't comment. Coming on to forums spouting off pedantic nonsense is unhelpful, and actually quite rude. Commented Sep 26, 2013 at 21:09
  • 9
    old post but there is a difference between "you should never" and "browser should not allow". It is precisely because web dev are pushing the limits, that browser devs have to put limits in place, for the good of the users. Otherwise we'd still be in a web of customised colorful scrollbars and shake-the-window onload. Commented Apr 17, 2014 at 12:58
  • 3
    Old revive but hot damn thank you @NathanCrause! I am coming to the point where I need to release Accessibility functionality as some users can't see as well, and not being able to change the browser zoom is making my life hard. CSS Zoom just doesn't work well with jquery ui Commented Feb 23, 2015 at 6:34

12 Answers 12

81

Possible in IE and chrome although it does not work in firefox:

<script>
   function toggleZoomScreen() {
       document.body.style.zoom = "80%";
   } 
</script>

<img src="example.jpg" alt="example" onclick="toggleZoomScreen()">
Sign up to request clarification or add additional context in comments.

4 Comments

Jourkey explicitly asked for non CSS zoom.
This is just changing the CSS zoom value inline on body, which does exactly the opposite of what the question asked.
Don't forget that this zoom state likely needs to be persistently saved and managed in a session variable and replayed each page load.
According to MDN, this is non-standard and not recommended in production. Source: developer.mozilla.org/en-US/docs/Web/CSS/zoom
57

I would say not possible in most browsers, at least not without some additional plugins. And in any case I would try to avoid relying on the browser's zoom as the implementations vary (some browsers only zoom the fonts, others zoom the images, too etc). Unless you don't care much about user experience.

If you need a more reliable zoom, then consider zooming the page fonts and images with JavaScript and CSS, or possibly on the server side. The image and layout scaling issues could be addressed this way. Of course, this requires a bit more work.

2 Comments

Hi, what about reducing the application rendering zoom level?
Not sure what you mean by that comment? Nowadays, though, the CSS zoom (as per the other answer stackoverflow.com/a/13840578/94956) would probably work as intended for most cases, except Firefox.
30

Try if this works for you. This works on FF, IE8+ and chrome. The else part applies for non-firefox browsers. Though this gives you a zoom effect, it does not actually modify the zoom value at browser level.

    var currFFZoom = 1;
    var currIEZoom = 100;

    $('#plusBtn').on('click',function(){
        if ($.browser.mozilla){
            var step = 0.02;
            currFFZoom += step; 
            $('body').css('MozTransform','scale(' + currFFZoom + ')');
        } else {
            var step = 2;
            currIEZoom += step;
            $('body').css('zoom', ' ' + currIEZoom + '%');
        }
    });

    $('#minusBtn').on('click',function(){
        if ($.browser.mozilla){
            var step = 0.02;
            currFFZoom -= step;                 
            $('body').css('MozTransform','scale(' + currFFZoom + ')');

        } else {
            var step = 2;
            currIEZoom -= step;
            $('body').css('zoom', ' ' + currIEZoom + '%');
        }
    });

5 Comments

you must have jquery 1.8.3 or jquery migrate plugin (to use $.browser)
For consistency, in MozTransform case, set the origin:
You should nowadays just be able to set transform: scale(..) in all browsers. MozTransform doesn't exist even in current versions of Firefox.
You might want to set transform-origin: 50% 0;
OP explicitly asked to not use CSS zoom.
13

You can use the CSS3 zoom function, but I have not tested it yet with jQuery. Will try now and let you know. UPDATE: tested it, works but it's fun

5 Comments

yeah, totally not. Any idea for cross-browser? UPDATE: no need, just checked the post above! cheers
Seems to work in Chrome and Safari, but not Firefox.
Broken in iPad OS Safari
Works in Chrome as of Jan 2021. Can check other compatibility here: developer.mozilla.org/en-US/docs/Web/CSS/zoom Obviously not recommended but good for a quick hack
OP explicitly asked to not use CSS zoom.
3

I could't find a way to change the actual browser zoom level, but you can get pretty close with CSS transform: scale(). Here is my solution based on JavaScript and jQuery:

<!-- 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>

<script>
    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>

Comments

2

as the the accepted answer mentioned, you can enlarge the fontSize css attribute of the element in DOM one by one, the following code for your reference.

 <script>
    var factor = 1.2;
    var all = document.getElementsByTagName("*");
    for (var i=0, max=all.length; i < max; i++) {
        var style = window.getComputedStyle(all[i]);
        var fontSize = style.getPropertyValue('font-size');

        if(fontSize){
            all[i].style.fontSize=(parseFloat(fontSize)*factor)+"px";
        }
        if(all[i].nodeName === "IMG"){
            var width=style.getPropertyValue('width');
            var height=style.getPropertyValue('height');
            all[i].style.height = (parseFloat(height)*factor)+"px";
            all[i].style.width = (parseFloat(width)*factor)+"px";
        }
    }
</script>

Comments

-1

Easiest Solution

To get window zoom (not CSS zoom), there are some ways, but the easiest of them is as follows:

(function() {
    window.addEventListener('resize', evt => {
        let zoom = (window.outerWidth / window.innerWidth).toFixed(2)
        console.log('zoom: ', zoom, '%')
    })
})();

Another Way

An alternative way is window.devicePixelRatio, but it may display incorrect value, depending on screen resolution (specially with multiple screens).

Comments

-1

browser.tabs.setZoom() should handle this case.

let zooming = browser.tabs.setZoom(
  tabId,           // optional integer
  zoomFactor       // number
)

See the MDN Docs: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/setZoom

1 Comment

The browser.tabs.setZoom() function is part of the WebExtensions API, which is typically used in browser extensions. You cannot use it directly as javascript on the website.
-2

<html>
  <head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
        var currFFZoom = 1;
        var currIEZoom = 100;

        function plus(){
            //alert('sad');
                var step = 0.02;
                currFFZoom += step;
                $('body').css('MozTransform','scale(' + currFFZoom + ')');
                var stepie = 2;
                currIEZoom += stepie;
                $('body').css('zoom', ' ' + currIEZoom + '%');

        };
        function minus(){
            //alert('sad');
                var step = 0.02;
                currFFZoom -= step;
                $('body').css('MozTransform','scale(' + currFFZoom + ')');
                var stepie = 2;
                currIEZoom -= stepie;
                $('body').css('zoom', ' ' + currIEZoom + '%');
        };
    </script>
    </head>
<body>
<!--zoom controls-->
                        <a id="minusBtn" onclick="minus()">------</a>
                        <a id="plusBtn" onclick="plus()">++++++</a>
  </body>
</html>

in Firefox will not change the zoom only change scale!!!

1 Comment

Once again, this is CSS zooming, which is undesirable by the question.
-2

You can use Window.devicePixelRatio and Window.matchMedia()

const onChange = e => {
  const pr = window.devicePixelRatio;
  const media = `(resolution: ${pr}dppx)`;
  const mql = matchMedia(media);

  const prString = (pr * 100).toFixed(0);
  const textContent = `${prString}% (${pr.toFixed(2)})`;

  console.log(textContent);
  document.getElementById('out').append(
    Object.assign(document.createElement('li'), {textContent})
  )

  mql.addEventListener('change', onChange, {once: true});
};

document.getElementById('checkZoom').addEventListener('click', e => onChange());

onChange();
<button id="checkZoom">get Zoom</button>
<ul id="out"></ul>

1 Comment

The question is how to change it, not detect it.
-3

You can target which part of CSS zooming out and in, or the entire document.body.style.zoom

You can set the maximum and minimum zoom levels. Meaning, more clicks on the button (+) or (-) will not zoom in more or zoom out more.

var zoomingTarget = document.querySelector('.zooming-target')
var zoomInTool = document.getElementById('zoom-in');
var zoomOutTool = document.getElementById('zoom-out');

let zoomIndex = 0;

function zooming () {
    if (zoomIndex > 2) {
        zoomIndex = 2
    } else if (zoomIndex < -2) {
        zoomIndex = -2
    }
    zoomingTarget.style.zoom = "calc(100% + " + zoomIndex*10 + "%)";
}

Now make the buttons (+) and (-) work.

zoomInTool.addEventListener('click', () => {
    zoomIndex++;
    if(zoomIndex == 0) {
        console.log('zoom level is 100%')
    }
    zooming();
})

zoomOutTool.addEventListener('click', () => {
    zoomIndex--
    if(zoomIndex == 0) {
        console.log('zoom level is 100%')
    }
    zooming();
})

Since style.zoom doesn't work on Firefox, consider using style.transform = scale(x,y).

1 Comment

OP explicitly asked to not use CSS zoom.
-3

I fixed by the below code.

HTML:

<div class="mt-5"
        [ngStyle]="getStyles()">

TS:

getStyles() {
        const screenWidth = screen.width;
        const windowWidth = window.innerWidth;
        if (windowWidth != screenWidth) {
            const percentDifference = Math.ceil((screenWidth / windowWidth) * 100);
            if (percentDifference > 100) {
                this.bannerBackgroundImageSize = '20%, 74%';
            } else if (percentDifference === 100) {
                this.bannerBackgroundImageSize = '20%, 72%';
            } else if (percentDifference >= 90 && percentDifference <= 99) {
                this.bannerBackgroundImageSize = '25%, 70%';
            } else if (percentDifference >= 80 && percentDifference <= 89) {
                this.bannerBackgroundImageSize = '28%, 68%';
            } else if (percentDifference >= 75 && percentDifference <= 79) {
                this.bannerBackgroundImageSize = '29%, 67%';
            } else if (percentDifference >= 67 && percentDifference <= 74) {
                this.bannerBackgroundImageSize = '30%, 65%';
            } else if (percentDifference >= 50 && percentDifference <= 66) {
                this.bannerBackgroundImageSize = '30%, 61%';
            } else if (percentDifference < 50) {
                this.bannerBackgroundImageSize = '30%, 58%';
            }
        } else {
            this.bannerBackgroundImageSize = '20%, 72%';
        }
        const myStyles = {
            'background-size': this.bannerBackgroundImageSize,
        };
        return myStyles;
    }

I Hope this will work with all zoom levels and it can be considered with all styles.

Useful links:

https://css-tricks.com/can-javascript-detect-the-browsers-zoom-level/

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images

1 Comment

This just changes the background and not the page.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.