8

I'm trying to solve an issue with css "position:fixed" property on mobile browsers. I have a fixed div:

<div id="logo">
...other content here...
</div>

with css:

#logo{
    position: fixed;
    -webkit-backface-visibility: hidden;
    bottom: 100px;
    right: 0px;
    width: 32px;
    height: 32px;
}

So, usually the behaviour is exactly the desired one, with the div position always on the bottom right of the window, indipendently of the scroll position. My issue is that on mobile browsers, when the users zoom the page, after a certain zoom level the div position is wrong (sometimes the div disappear out of the window).

I know that fixed position is not well supported on mobile browsers, but I wonder if there is some workaround. I tried with this js code onScroll event:

window.addEventListener('scroll', function(e){
    drag.style['-webkit-transform'] = 'scale(' +window.innerWidth/document.documentElement.clientWidth + ')';\\I want to avoid zoom on this element
    var r = logo.getBoundingClientRect();
    var w = window.innerWidth;
    var h = window.innerHeight;
    if(r.right != w){
        rOff = r.right - w;
        logo.style.right = rOff;
    }
    if(r.top+132 != h){\
        tOff = r.top + 132 - h;
        logo.style.bottom = tOff;
    }
});

Unfortunately, the code seems to return the wrong position.

Does anyone have any tip?

Guillaume Algis
  • 10,705
  • 6
  • 44
  • 72
user3098549
  • 1,171
  • 2
  • 13
  • 26
  • Could you fix the viewport so the user can't zoom in? – Chris Pateman Oct 04 '14 at 16:04
  • 1
    No, I want to let the user the possibility to zoom the page – user3098549 Oct 04 '14 at 16:05
  • 1
    Not 100% without a working example,but could the wrong positioning you are seeing be because the fixed div is relative to the document and not fixed to the window. So when you zoom in it is still bottom right but off the screen. Can you put it in a jsfiddle? – Chris Pateman Oct 04 '14 at 16:17
  • I think it's not possible to test it on jsfiddle because the code is executed inside the result iframe, so you cannot zoom it unless you zoom the whole page – user3098549 Oct 05 '14 at 11:57

4 Answers4

2

Ok, that's how I solved the issue...I hope that could help anyone to simulate fixed position on iOS devices.

  1. I switched the position from fixed to absolute;
  2. Attach to window a listener to get the new position when the page is scrolled or zoomed, setting window.onscroll and window.onresize events with the following function:
function position() {
    drag.style.left = window.innerWidth + window.pageXOffset - 32 + 'px';
    drag.style.top = window.innerHeight + window.pageYOffset - 132 + 'px';
}
Guillaume Algis
  • 10,705
  • 6
  • 44
  • 72
user3098549
  • 1,171
  • 2
  • 13
  • 26
  • Switching from `fixed` to `absolute` on zoom is the way the go. Like this you leave device or browser zoom as the user wants to use it, have the website accessible for users who want to use the zoom and you don't have to worry about zoom level or future browser or device changes regarding zoom functionality. – lowtechsun Jan 24 '17 at 12:23
1

Do you want to catch if zoom is active?

There's no window.onZoom listener, but you can read this thread: Catch browser's "zoom" event in JavaScript

and this answer: https://stackoverflow.com/a/995967/3616853

There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it. I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3 You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other. There's no way to tell if the page is zoomed if they load your page while zoomed.

Community
  • 1
  • 1
grubino
  • 21
  • 3
  • 1
    Please provide the relevant information in the answer itself. The way it is now, it will become useless as soon as the links go dead. – toniedzwiedz Oct 07 '14 at 14:52
  • I don't need to catch if zoom is active, I've already catched the event. I want to know how to get the right offset for my element according to zoom scale factor. It seems that the issue only happens on iOS devices with zoom>1.4X – user3098549 Oct 07 '14 at 15:09
  • @user3098549 you can create an separated style sheet for specific devices, and handle the offset right there... or is not an option? – grubino Oct 07 '14 at 15:40
  • This is not the issue I want to solve...my problem is about zoom, not about device screen size – user3098549 Oct 07 '14 at 15:42
0

Just a theory, but you may want to try setting the bottom/right positions in % rather than px.

I think what you're seeing when using pixel measurements is just the zoom effecting the pixels. Or to put it better, when you zoom-in the pixels appear larger and that throws off the position of the element, even pushing it out of the view-port on smaller screens.

Example using pixel positioning
Notice that even on a desktop as you zoom-in and out the element appears to move up and down?

Example using percent positioning
In this example the element appears to stay in the bottom right corner, because it is always positioned at 10% from the bottom of the view-port.

#logo{
    position: fixed;
    -webkit-backface-visibility: hidden;
    bottom:10%;
    right: 0; 
    width: 32px;
    height: 32px;
}
apaul
  • 16,092
  • 8
  • 47
  • 82
0

Having two different z-index for the logo and the rest of the page could help. Allowing zooming only to the rest of the page and not to the z-index layer where logo is included. So, this might not affect the stretching on the logo.

We can

  1. Implement a ZOOM listener
  2. Attach it to browser
  3. Make the zoom listener change the zoom level of the element (modify the elements position) using z-index as a factor.
Satt
  • 63
  • 1
  • 1
  • 8