2

I have an element with position fixed (pinned to any corner) on a page (which I do not necessarily have control over the meta viewport tag - it is an embedded widget for third party sites). On Mobile Safari when the user pinch zooms the page at a certain point the viewport becomes larger than the visible area. At that point the fixed position element stays attached to the viewport and is not necessarily in the visible area.

I would like to compare two widths: the width of the visible area and the width of the viewport. I believe the size of the visible area is window.innerWidth. I am not sure how to measure the viewport.

I have been trying to see the relationships between:

  • document.documentElement.clientWidth
  • screen.width
  • window.innerWidth
  • window.outerWidth

...But have not been able to see anything obvious.

Piwakawaka
  • 459
  • 5
  • 15

1 Answers1

0

This is butt ugly but it does show some code that almost works (view on iOS to see it working. Use a desktop and click edit at top right of page to see or edit code):

https://jsbin.com/jopamu (iOS only)

The trick with the "overzoom" calculation is nasty but it does compensate somewhat for the multiple viewport zooms. It is a complex problem to solve because there are competing issues:

  • pinch-zoom
  • zoom due to input focus
  • the "position:fixed" zoom
  • potentially the OS (accessibility) zoom

The possible solutions I have found are:

  1. Position the menu using the calculations above and position:absolute - updating the left/top in onscroll event. Has ugly juddering (can improve a little by hiding and only showing when zooming/scrolling finishes).

  2. Position the menu using position:fixed but change the left/top to correct the menu position as zooming/scrolling occurs. Much less judder but I couldn't quite get it 100% reliable (some race condition).

  3. Not suitable for your case (and highly unrecommended due to risk of breaking things): you can prevent pinch zooming and iOS10 double-click zooming by cancelling default on touchstart. Difficult because it needs many other workarounds so normal touch works, and needs synthetic scrolling and zooming (but has ugly side effects such as preventing scrolling working sometimes and also interferes with accessability e.g. if voice accessability turned on etc etc).

If you just want to see the widths then use the older version:https://output.jsbin.com/jopamu/6

Community
  • 1
  • 1
robocat
  • 4,857
  • 40
  • 62