This library is under active development. Please email us if you’re ready to use it in a production environment.
Mobile Viewport Control
This JavaScript library attempts to solve the hard problem of creating a
full-window modal experience for mobile browsers. The goal is to allow
it to be dropped into any page regardless of its viewport settings. It does
this by attempting to control the mobile viewport and by hiding all elements
except the one you are trying to modalize.
--
[![scroll][scroll-gif]][scroll-gfy] | [![zoom][zoom-gif]][zoom-gfy] |
__Figure 1.__ Scrolling | __Figure 2.__ Zooming + Scrolling |
--
Background. The viewport is the visible part of the webpage on your
screen (see quirksmode [1] [2]). It is controlled by two things: scroll
and zoom. The user can swipe to scroll and pinch to zoom. A JavaScript
developer can control the scroll programmatically, but there is no officially
supported method for controlling the zoom programmatically. However, we do
have a de facto standard for limiting and initializing the zoom:
<head>
<meta name="viewport" content="initial-scale=1">
<meta name="viewport" content="minimum-scale=0">
<meta name="viewport" content="maximum-scale=10">
</head>
Workaround. There is an undocumented feature that allows us to modify the
viewport state at runtime by adding and modifying viewport tags. There are
caveats depending on the browser. The goal of this library is to identify and
workaround these caveats until there is a standard for programmatically
controlling zoom. We have researched and tested on multiple platforms, though
we are currently focusing support for Mobile Safari and WebViews on iOS 7, 8, and 9.
(See Compatibility Testing)
Modals are the Use-Case. Viewport settings vary widely across different
webpages, making it hard to create drop-in modal experiences that work
everywhere (see Stripe Checkout and Auth0 Lock). For browsers that cannot
create pop-up tabs and for pages where redirection is not an option, this
library can help fill in the gaps.
UPDATE: See the upcoming Payment Request API for native mobile checkout modals for the web.
--
[![freeze][freeze-gif]][freeze-gfy] | [![isolate][isolate-gif]][isolate-gfy] |
__Figure 3.__ Freezing and Thawing | __Figure 4.__ Isolating the Modal |
--
The Abstraction. This library provides a limited abstraction for
controlling zoom: freezing and thawing. (See Figure 3). Freezing will lock
the zoom to a given scale. Thawing will restore the viewport to what it was
before freezing, while also restoring the appropriate zoom limits (i.e. min and
max). Thawing in this way is useful in the context of a modal.
Isolating the Modal. The freeze/thaw functions are designed to be used in
conjunction with a third operation: isolation. (See Figure 4). This is done
by passing an optional element ID to the freeze function, which you would
presumably wish to be the full-window modal. This temporarily applies CSS
rules to ensure with high confidence that all elements except the given element
are collapsed (via display:none
). You can then style your element to fill
the window as a modal. Thawing will restore the page back to what it was
before.
Usage
npm install mobile-viewport-control
const viewport = require('mobile-viewport-control');
viewport.freeze(1.0, () => console.log('notified when frozen!'));
viewport.thaw(() => console.log('notified when thawed!'));
Additionally, to freeze the scroll area to a given element, you can pass an
element ID as the second argument. We do this by temporarily hiding everything
else on the page. Just make sure your element is a direct child of
document.body
.
viewport.freeze(1.0, 'myElementID');
Testing
Please see Compatibility Testing.
License
ISC License
--
Source code for the animated figures above: mobile-viewport-control-viz