forked from WICG/visual-viewport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
301 lines (290 loc) · 14.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<!DOCTYPE html>
<html>
<head>
<title>Visual Viewport API</title>
<meta charset='utf-8'>
<script src='https://www.w3.org/Tools/respec/respec-w3c-common'
async class='remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "CG-DRAFT",
shortName: "visualviewport",
edDraftURI: "https://wicg.github.io/visual-viewport/",
testSuiteURI: "https://github.com/web-platform-tests/wpt/tree/master/visual-viewport",
editors: [
{ name: "David Bokan",
url: "",
company: "Google",
companyURL: "https://www.google.com/" },
],
otherLinks: [{
key: 'Participation',
data: [
{
value: 'GitHub repository',
href: 'https://github.com/WICG/visual-viewport/'
}, {
value: 'File a bug / view open issues',
href: 'https://github.com/WICG/visual-viewport/issues'
}, {
value: 'Feedback / discussion in the WICG',
href: 'https://discourse.wicg.io/t/explicit-api-for-visual-viewport/1399'
}
]
}],
wg: "Web Platform Incubator Community Group",
wgURI: "https://www.w3.org/community/wicg/",
};
</script>
</head>
<body>
<section id='abstract'>
<p>
The APIs introduced by this document provide authors with a way to determine
and interact with the properties of the visual viewport.
</p>
</section>
<section id='sotd'>
<p>
TODO
</p>
</section>
<section id="intro" class="informative">
<h2>Introduction</h2>
<p>
Some user agents have split their viewport into two conceptual viewports, colloquially
known as the <em>visual</em> and <em>layout</em> viewports. This separation is useful in
enabling a user agent (UA) with a small screen to allow the user to zoom in on parts of the page
without causing the page to respond, for example, by obscuring the user's view with
<code>position: fixed</code> elements. As another example, mobile UAs often provide an <em>on-screen
keyboard</em> (OSK) for user input. Without the visual/layout split, a <code>position: fixed</code>
element would be pushed up when the OSK is shown, obscuring the user's view. Informally,
the layout viewport is what the web page uses when laying out its UI while the visual viewport
is the box on the page that the user can currently see, accounting for transient UI features like
pinch-zoom and the OSK.
</p>
<p>
The existing APIs provided by UAs are ambiguous about which viewport they're relative to. For
example, <code>document.scrollingElement.scrollLeft</code> returns the scroll position of the
visual viewport while <code>document.scrollingElement.clientWidth</code> returns the width of
the layout viewport. <code>getBoundingClientRect</code> returns the rect relative to the layout
viewport while positioning non-fixed elements relative to the layout viewport is difficult. This
makes building UI that responds to scrolls across mobile and desktop UAs difficult. Worse still,
there's no way for the developer to be notified when the visual viewport changes. For example,
the only way to know when the user has zoomed is to poll or listen to touch events and continually
check <code>window.innerWidth</code>.
</p>
<p>
The Visual Viewport API is designed to provide an explicit mechanism for developers to query and
potentially modify the properties of the visual viewport. It also introduces events that allow the
page to listen for changes in the visual viewport, allowing UX that explicitly wants to react to
these changes to do so. For example, the page could keep a small text-formatting bar above the OSK.
</p>
</section>
<section id="conformance"></section>
<section>
<h2>Description</h2>
<section data-dfn-for="Window">
<h3>Extensions to the <code>Window</code> interface</h3>
<p>
This document extends the <code><dfn data-cite="!HTML#window">Window</dfn></code>
interface defined by [[!HTML]].
</p>
<pre class="idl">
partial interface Window {
[SameObject, Replaceable] readonly attribute VisualViewport visualViewport;
};
</pre>
<dl>
<dt><dfn data-dfn-for="Window">visualViewport</dfn></dt>
<dd>
If the <a>window</a>'s <dfn data-cite="!HTML#concept-document-window">associated Document</dfn> is
<dfn data-cite="!HTML#fully-active">fully active</dfn>, return the
<a>VisualViewport</a> object associated with it. Otherwise, return null.
<p class="note">
Intuitively, the VisualViewport object is only returned and useful for a <a>window</a> whose
<dfn data-cite="!HTML#document">Document</dfn> is currently being presented. If a reference is retained to a
<a>VisualViewport</a> whose <a>associated Document</a> is not being currently presented, the
values in that <a>VisualViewport</a> must not reveal any information about the
<dfn data-cite="!HTML#browsing-context">browsing context</dfn>.
<p>
</dd>
</dl>
</section>
<section data-dfn-for="VisualViewport">
<h3>The <dfn><code>VisualViewport</code></dfn> interface</h3>
<p>
A <a>VisualViewport</a> object represents the visual viewport for a <a>window</a>'s
<a>browsing context</a>. Each <a>window</a> on a page will have a unique
<a>VisualViewport</a> object. This object represents the properties of the <a>window</a>'s
<a>associated Document</a>'s <a>browsing context</a> when that <a>Document</a> is
</a>fully active</a>.
<p class="example">
For example: if a script retains a reference to a <a>VisualViewport</a> for an iframe, then
navigates the iframe to another location, reading the integral values from the
<a>VisualViewport</a> reference will return 0 because its window's Document is no longer
being presented in a browsing content; it is no longer fully-active.
<p>
</p>
<pre class="idl">
[Exposed=Window]
interface VisualViewport : EventTarget {
readonly attribute double offsetLeft;
readonly attribute double offsetTop;
readonly attribute double pageLeft;
readonly attribute double pageTop;
readonly attribute double width;
readonly attribute double height;
readonly attribute double scale;
attribute EventHandler onresize;
attribute EventHandler onscroll;
};
</pre>
<dl>
<dt><dfn>offsetLeft</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, return the offset of the left edge of the visual viewport from the left edge
of the layout viewport in CSS pixels.
</p>
</dd>
<dt><dfn>offsetTop</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, return the offset of the top edge of the visual viewport from the top edge of
the layout viewport in CSS pixels.
</p>
</dd>
<dt><dfn>pageLeft</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, return the x-coordinate, relative to the
<dfn data-cite="!CSS-DISPLAY-3#initial-containing-block">initial containing block</dfn>
origin, of the left edge of the visual viewport in CSS pixels.
</p>
</dd>
<dt><dfn>pageTop</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, return the y-coordinate, relative to the <a>initial containing block</a>
origin, of the top edge of the visual viewport in CSS pixels.
</p>
</dd>
<dt><dfn>width</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, returs the width of the visual viewport in CSS pixels. This value
excludes the width of any rendered
<dfn data-cite="!CSS-OVERFLOW-4#classic-scrollbars">classic scrollbar</dfn>
that is fixed to the visual viewport.
<div class="note">
A scrollbar that is fixed to the visual viewport is one that does
not change size or location as the visual viewport is zoomed and
panned.
Because this value is in CSS pixels, when excluding the scrollbar
width the UA must account for how large the scrollbar is in CSS
pixels. That is, the amount excluded is lessened if the viewport
is zoomed in and the scrollbars don't change size to the user.
</div>
</p>
</dd>
<dt><dfn>height</dfn></dt>
<dd>
<p>
If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0.
</p>
<p>
Otherwise, return the height of the visual viewport in CSS pixels. This value
excludes the height of any rendered
<a>classic scrollbar</a>
that is fixed to the visual viewport.
<div class="note">
Because both the width and height attributes are expressed in CSS pixels, increasing either
page-zoom or pinch-zoom will cause these values to shrink.
</div>
</p>
</dd>
<dt><dfn>scale</dfn></dt>
<dd>
Returns the pinch-zoom scaling factor applied to the visual viewport. It can be computed using the following algorithm:
<ol>
<li data-md><p>If the <a>window</a>'s <a>associated Document</a> is not <a>fully active</a>, return 0 and abort these steps.</p></li>
<li data-md><p>If there is no output device, return 1 and abort these steps.</p></li>
<li data-md>
<p>
Let <var>CSS pixel size</var> be the size of a CSS <code><dfn data-cite="!CSS3-VALUES#reference-pixel">reference pixel</dfn></code>
at the current <dfn data-cite="!CSSOM-VIEW#page-zoom">page zoom</dfn> and
<dfn data-cite="!CSSOM-VIEW#pinch-zoom">pinch zoom</dfn> scales.
</p>
</li>
<li data-md><p>Let <var>device pixel size</var> be the size of a device pixel of the output device.</p></li>
<li data-md>
<p>
Let <var>device independent pixel size</var> be the product of <var>device pixel size</var> and the
<dfn data-cite="CSSOM-VIEW#dom-window-devicepixelratio">devicePixelRatio</dfn>
</p>
</li>
<li data-md><p>Return the result of dividing the <var>CSS pixel size</var> by the <var>device independent pixel size</var>.</li>
</ol>
<div class="note">
Although it is referred to as the pinch-zoom scaling factor, it can be affected through means other than pinch-zooming. e.g. When the UA centers and zooms in a focused edit box.
</div>
</dd>
<dt><dfn>onresize</dfn></dt>
<dd>
Event handler attribute for the resize event.
</dd>
<dt><dfn>onscroll</dfn></dt>
<dd>
Event handler attribute for the scroll event.
</dd>
</dl>
</section>
<section>
<h3>Events</h3>
<h4>Resizing the viewport</h4>
<p data-link-for="VisualViewport">
The user agent must fire an <dfn data-cite="!DOM#event">Event</dfn>
named <code>resize</code> at the <a>VisualViewport</a> object if any
of its <a>height</a>, <a>width</a>, or <a>scale</a> attributes change
(e.g. in response to user interaction, scrollbars
appearing/disappearing). The resize event must not bubble and must
not be cancellable.
</p>
<p>
These events follow the procedure defined in
<dfn data-cite="!CSSOM-VIEW#resizing-viewports">section 12.1</dfn> of the
CSSOM View module.
</p>
<h4>Scrolling</h4>
<p data-link-for="VisualViewport">
The user agent must fire an <a>Event</a> named <code>scroll</code>
at the <a>VisualViewport</a> object if either of its <a>offsetTop</a>
or <a>offsetLeft</a> attributes change (e.g in response to user
interaction, by an API, or by the resize of the visual viewport). The
scroll event must not bubble and must not be cancellable.
</p>
<p>
These events follow the procedure defined in
<dfn data-cite="!CSSOM-VIEW#scrolling-events">section 12.2</dfn>
of the CSSOM View module.
</p>
</section>
</section>
</body>
</html>