16

In my web app, I have some thumbnails that open a lightbox when clicked. On mobile, the thumbnails are small and the user typically zooms in. The problem is that when they click to play it, the lightbox is outside of the viewable area (they have to scroll to the lightbox to see the video). Is it possible to force a mobile browser to zoom out so they can see the whole page?

Making the page more responsive is not an option right now; it is a fairly large web application and it would take a huge amount of time to refactor.

Andrew Hassan
  • 591
  • 2
  • 5
  • 15
  • maybe this can help you? http://stackoverflow.com/questions/17440196/zoom-in-and-zoom-out-functionality-in-jquery-mobile-or-javascript – Vincent Hogendoorn Mar 25 '14 at 15:40
  • 2
    I saw that post earlier and I don't think it'll help me. I'm referring to the pinch zoom that mobile devices can do, not zooming with CSS. As an alternative to this, is there a way to detect the zoom level of the browser? AFAIK, tools like `detect-zoom` are broken with newer versions of the browsers. – Andrew Hassan Mar 25 '14 at 19:24

5 Answers5

14

Dug through a lot of other questions trying to get something to zoom out to fit the entire page. This question was the most relevant to my needs, but had no answers. I found this similar question which had a solution, although implemented differently, and not what I needed.

I came up with this, which seems to work in Android at least.

  1. initial-scale=0.1: Zooms out really far. Should reveal your whole website (and then some)
  2. width=1200: Overwrites initial-scale, sets the device width to 1200.

You'll want to change 1200 to be the width of your site. If your site is responsive then you can probably just use initial-scale=1. But if your site is responsive, you probably don't need this in the first place.

function zoomOutMobile() {
  var viewport = document.querySelector('meta[name="viewport"]');

  if ( viewport ) {
    viewport.content = "initial-scale=0.1";
    viewport.content = "width=1200";
  }
}

zoomOutMobile();
Community
  • 1
  • 1
Radley Sustaire
  • 3,382
  • 9
  • 37
  • 48
  • This worked well to resize the viewport on android and windows phones for me. Thanks! – zbarrier Dec 11 '15 at 21:34
  • Nice script ! Thanks a lot, working on all devices (Android, iPhone, iPad, Windows Phone) !! (Don't forget to put it at the end of html) – Pierre C. Aug 23 '17 at 11:56
  • Not working if checked "Desktop site" - android chrome. How to solve? – Erekle M. Dec 02 '20 at 08:04
  • Thank you! This worked for my mobile needs. I modified the width value and it works very well! – mateostabio Jul 20 '21 at 17:00
  • I think you need to write: `viewport.content = 'initial-scale=1, width=1200';` Otherwise only the 'width=1200' will be applied. This goes for @Davey's solution below as well. – Esger Jul 11 '22 at 10:30
  • @Radley Sustaire I've small doubt about Force web browser zoom out with Javascript! kindly said to me – R sukumar Oct 04 '22 at 12:17
4

Similar to Radley Sustaire's solution I managed to force unzoom whenever the device is turned in React with

  zoomOutMobile = () => {
    const viewport = document.querySelector('meta[name="viewport"]');

    if ( viewport ) {
      viewport.content = 'initial-scale=1';
      viewport.content = 'width=device-width';
    }
  }

and inside my render

this.zoomOutMobile();

1 edge case I found was this did not work on the Firefox mobile browser

Davey
  • 119
  • 2
  • 10
  • For some reason I had to swap the two `viewport.content = ...` statements for it to work on the first call. Subsequent calls worked fine no matter the order. – simlmx Aug 16 '21 at 18:35
  • I think you need to write: `viewport.content = 'initial-scale=1, width=device-width';` Otherwise only the 'width=device-width' will be applied. – Esger Jul 11 '22 at 14:50
3

I ran in a similar problem, rather the opposite, I guess, but the solution is most certainly the same. In my case, I have a thumbnail that people click, that opens a "popup" where users are likely to zoom in to see better and once done I want to return to the normal page with a scale of 1.0.

To do that I looked around quite a bit until I understood what happens and could then write the correct code.

The viewport definition in the meta data is a live value. When changed, the system takes the new value in consideration and fixes the rendering accordingly. However, the "when changed" is detected by the GUI and while the JavaScript code is running, the GUI thread is mostly blocked...

With that in mind, it meant that doing something like this would fail:

viewport = jQuery("meta[name='viewport']");
original = viewport.attr("content");
force_scale = original + ", maximum-scale=1";
viewport.attr("content", force_scale); // IGNORED!
viewport.attr("content", original);

So, since the only way I found to fix the scale is to force it by making a change that I do not want to keep, I have to reset back to the original. But the intermediary changes are not viewed and act upon (great optimization!) so how do we resolve that issue? I used the setTimeout() function:

viewport = jQuery("meta[name='viewport']");
original = viewport.attr("content");
force_scale = original + ", maximum-scale=1";
viewport.attr("content", force_scale);
setTimeout(function()
    {
        viewport.attr("content", original);
    }, 100);

Here I sleep 100ms before resetting the viewport back to what I consider normal. That way the viewport takes the maximum-scale=1 parameter in account, then it times out and removes that parameter. The scale was changed back to 1 in the process and restoring my original (which does not have a maximum-scale parameter) works as expected (i.e. I can scale the interface again.)

WARNING 1: If you have a maximum-scale parameter in your original, you probably want to replace it instead of just appending another value at the end like in my sample code. (i.e. force_scale = original.replace(/maximum-scale=[^,]+/, "maximum-scale=1") would do the replace--but that works only if there is already a maximum-scale, so you may first need to check to allow for either case.)

WARNING 2: I tried with 0ms instead of 100ms and it fails. This may differ from browser to browser, but the Mozilla family runs the immediately timed out timer code back to back, meaning that the GUI process would never get a chance to reset the scale back to 1 before executing the function to reset the viewport. Also I do know of a way to know that the current viewport values were worked on by the GUI... (i.e. this is a hack, unfortunately.)

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • It seems we are doing the same thing, allowing a visitor to tap a thumbnail, resulting in a bigger hi-res image appearing, which they can further expand. But of course when the image is dismissed, the user is left with an overly expanded page. You're solution looked great but didn't work, because it seems apple has decided to ignore viewport settings like this. so I guess we're all screwed. Have any suggestions? I wonder how Facebook allows the user to switch to a sizable photo and then return to completely normal. :-( – Randy Nov 22 '20 at 19:47
  • If I'm correct, facebook has an iframe for images. That means a _separate page_. So that could explain how theirs works... – Alexis Wilke Nov 23 '20 at 03:41
  • I was thinking it was something like that, although I considered a siple separate page as opposed to an iframe. I'll have to try it thanks! I guess a 'new page' open to a new window on a mobile phone has to open on the same screen, in which case if I did a 'window.close() after another tap/click event, it SHOULD switch back to the first screen. I'd LIKE to think that. I hate situations where I can only test with my own i-phone, and have to call all my android user friends to test for the same behavior. – Randy Nov 24 '20 at 17:52
  • Alexis --- I sent you a message via your "https://www.alexiswilke.me/contact" page. there was no confirmation so I don't know if you got it. But have a look? – Randy Nov 25 '20 at 23:07
  • @Randy There was a glitch, indeed. You'll have to try again. Sorry for the inconvenience! – Alexis Wilke Nov 25 '20 at 23:52
0

This one works for me

let sw = window.innerWidth;
let bw = $('body').width();
let ratio = sw / bw - 0.01;
$('html').css('zoom', ratio);
$('html').css('overflow-x', 'hidden');

Its fits html to screen and prevents from scrolling. But this is not a good idea and work not everywhere.

ikebastuz
  • 349
  • 1
  • 5
  • 13
0
var zoomreset = function() {
    var viewport = document.querySelector("meta[name='viewport']");
    viewport.content = "width=650, maximum-scale=0.635";
    setTimeout(function() {
        viewport.content = "width=650, maximum-scale=1";
    }, 350);
}
setTimeout(zoomreset, 150);

replace 650 with the width of your page

Gaby_64
  • 77
  • 7