Skip to content

[cssom-view-1] Introduce VisualViewport API #6339 #7316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 7, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 119 additions & 10 deletions cssom-view-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Can I Use URL: https://www.w3.org/TR/cssom-view-1/

<pre class='link-defaults'>
spec:css-ui-4; type:property; text:pointer-events
spec:css2; type:dfn; text:canvas
spec:css2; type:dfn; text:viewport
spec:html; type:dfn;
text: inert
Expand Down Expand Up @@ -265,6 +266,22 @@ The <dfn>ending edges</dfn> of a particular set of edges of a box or element are
<dd>The top and right edges.
</dl>

The <dfn>visual viewport</dfn> is a kind of <a>viewport</a> whose <a>scrolling area</a> is another <a>viewport</a>,
called the <dfn>layout viewport</dfn>.

In addition to scrolling, the <a>visual viewport</a> may also apply a scale transform to its <a>layout viewport</a>.
This transform is applied to the <a>canvas</a> of the <a>layout viewport</a> and does not affect its internal coordinate space.

Note: The scale transform of the visual viewport is often referred to as "pinch-zoom". Conceptually, this transform
changes the size of the CSS <a>reference pixel</a> but changes the size of the layout viewport proportionally so that it
does not cause reflow of the page's contents.

The magnitude of the scale transform is known as the <a>visual viewport</a>'s <dfn>scale factor</dfn>.

The {{VisualViewport}} object has an <dfn for=visualviewport>associated document</dfn>, which is a {{Document}} object.
It is the <a for="/">associated document</a> of the owner {{Window}} of {{VisualViewport}}. The <a>layout viewport</a>
is the owner {{Window}}'s <a>viewport</a>.

For the purpose of the requirements in this specification,
elements that have a computed value of the 'display' property
that is ''table-column'' or ''table-column-group''
Expand Down Expand Up @@ -293,9 +310,12 @@ Note: This does not apply to e.g. {{matchMedia()}} as the units are explicitly g

<h3 id=zooming>Zooming</h3>

There are two kinds of zoom, <dfn>page zoom</dfn> which affects the size of the initial viewport<!-- XXX ref -->, and <dfn>pinch zoom</dfn> which acts like
There are two kinds of zoom, <dfn>page zoom</dfn> which affects the size of the initial viewport<!-- XXX ref -->, and the visual viewport <a>scale factor</a> which acts like
a magnifying glass and does not affect the initial viewport<!-- XXX ref --> or actual viewport<!-- XXX ref -->. [[!CSS-DEVICE-ADAPT]]

Note: The "scale factor" is often referred to as "pinch-zoom"; however, it can be affected through means other than
pinch-zooming. e.g. The user agent may zooms in on a focused input element to make it legible.


<h3 id=web-exposed-screen-information>Web-exposed screen information</h3>

Expand Down Expand Up @@ -391,6 +411,7 @@ dictionary ScrollToOptions : ScrollOptions {
partial interface Window {
[NewObject] MediaQueryList matchMedia(CSSOMString query);
[SameObject, Replaceable] readonly attribute Screen screen;
[SameObject, Replaceable] readonly attribute VisualViewport? visualViewport;

// browsing context
undefined moveTo(long x, long y);
Expand Down Expand Up @@ -432,7 +453,7 @@ When the <dfn method for=Window caniuse=matchmedia>matchMedia(<var>query</var>)<
<var>query</var>.
<li>Return a new {{MediaQueryList}} object,
with [=this=]'s
<a>associated <code>Document</code></a>
<a for="/">associated <code>Document</code></a>
as the <a for=MediaQueryList>document</a>,
with <var>parsed media query list</var> as its associated [=MediaQueryList/media query list=].
</ol>
Expand All @@ -443,6 +464,14 @@ associated with the {{Window}} object.
Note: Accessing {{Window/screen}} through a {{WindowProxy}} object might yield different
results when the {{Document}} is navigated.

If the <a for="/">associated document</a> is <a>fully active</a>, the <dfn attribute for=Window>visualViewport</dfn>
attribute must return the {{VisualViewport}} object associated with the {{Window}} object's <a for="/">associated
document</a>. Otherwise, it must return null.

Note: the VisualViewport object is only returned and useful for a window whose Document is currently being presented. If
a reference is retained to a VisualViewport whose associated Document is not being currently presented, the values in
that VisualViewport must not reveal any information about the browsing context.

The <dfn method for=Window>moveTo(<var>x</var>, <var>y</var>)</dfn> method must follow these steps:

1. Optionally, return.
Expand Down Expand Up @@ -585,7 +614,7 @@ attribute must return zero. <!--fingerprint-->
The <dfn attribute for=Window caniuse=devicepixelratio>devicePixelRatio</dfn> attribute must return the result of the following <dfn export>determine the device pixel ratio</dfn> algorithm:

1. If there is no output device, return 1 and abort these steps.
1. Let <var>CSS pixel size</var> be the size of a <a lt=px value>CSS pixel</a> at the current <a>page zoom</a> scale factor and at a <a>pinch zoom</a> scale factor of 1.0.
1. Let <var>CSS pixel size</var> be the size of a <a lt=px value>CSS pixel</a> at the current <a>page zoom</a> and using a <a>scale factor</a> of 1.0.
1. Let <var>device pixel size</var> be the vertical size of a device pixel of the output device.
1. Return the result of dividing <var>CSS pixel size</var> by <var>device pixel size</var>.

Expand Down Expand Up @@ -1645,6 +1674,76 @@ method must run the following steps:
<li><p class=issue>...
</ol>

<h2 id=visualViewport>VisualViewport</h2>

<h3 id="the-visualviewport-interface">The {{VisualViewport}} Interface</h3>

<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>

The <dfn attribute for=VisualViewport>offsetLeft</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the offset of the left edge of the <a>visual viewport</a> from the left edge
of the <a>layout viewport</a>.

The <dfn attribute for=VisualViewport>offsetTop</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the offset of the top edge of the <a>visual viewport</a> from the top edge
of the <a>layout viewport</a>.

The <dfn attribute for=VisualViewport>pageLeft</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the offset of the left edge of the <a>visual viewport</a> from the left edge
of the <a>initial containing block</a> of the <a>layout viewport</a>'s <a for="/">document</a>.

The <dfn attribute for=VisualViewport>pageTop</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the offset of the top edge of the <a>visual viewport</a> from the top edge
of the <a>initial containing block</a> of the <a>layout viewport</a>'s <a for="/">document</a>.

The <dfn attribute for=VisualViewport>width</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the width of the <a>visual viewport</a> excluding the width of any rendered vertical <a>classic
scrollbar</a> that is fixed to the visual viewport.

Note: Since this value is returned in CSS pixels, the value will decrease in magnitude if either <a>page zoom</a> or the
<a>scale factor</a> is increased.

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 as measured in CSS pixels. That is, the amount excluded decreases when zooming in
and increases when zooming out.

The <dfn attribute for=VisualViewport>height</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0.
1. Otherwise, return the height of the <a>visual viewport</a> excluding the height of any rendered horizontal <a>classic
scrollbar</a> that is fixed to the visual viewport.

The <dfn attribute for=VisualViewport>scale</dfn> attribute must run these steps:
1. If the <a>visual viewport</a>'s <a for=visualviewport>associated document</a> is not <a>fully active</a>, return 0
and abort these steps.
1. If there is no output device, return 1 and abort these steps.
1. Otherwise, return the <a>visual viewport</a>'s <a>scale factor</a>.

<dfn attribute for=VisualViewport>onresize</dfn> is the <a>event handler IDL attribute</a> for the <a event>resize</a> event.

<dfn attribute for=VisualViewport>onscroll</dfn> is the <a>event handler IDL attribute</a> for the <a event>scroll</a> event.

<h2 id=events>Events</h2>

Expand All @@ -1656,11 +1755,14 @@ When asked to <dfn export for=Document>run the resize steps</dfn> for a {{Docume

1. If <var>doc</var>'s <a>viewport</a> has had its width or height changed
(e.g. as a result of the user resizing the browser window,
or changing the <span>page zoom</span> scale factor,
or changing <span>page zoom</span>,
or an <code>iframe</code> element's dimensions are changed)
since the last time these steps were run,
<a>fire an event</a> named <a event>resize</a>
at the {{Window}} object associated with <var>doc</var>.
1. If the {{VisualViewport}} associated with <var>doc</var> has had its <a attribute for=VisualViewport>scale</a>,
<a attribute for=VisualViewport>width</a>, or <a attribute for=VisualViewport>height</a> properties changed since
the last time these steps were run, <a>fire an event</a> named <a event>resize</a> at the {{VisualViewport}}.


<h3 id=scrolling-events>Scrolling</h3>
Expand All @@ -1686,7 +1788,8 @@ When asked to <dfn export for=Document>run the scroll steps</dfn> for a {{Docume
1. For each item <var>target</var> in <var>doc</var>'s <a>pending scroll event targets</a>,
in the order they were added to the list, run these substeps:

1. If <var>target</var> is a {{Document}}, <a>fire an event</a> named <a event>scroll</a> that bubbles at <var>target</var>.
1. If <var>target</var> is a {{Document}}, <a>fire an event</a> named <a event>scroll</a> that bubbles at <var>target</var> and fire an event
named <a event>scroll</a> at the {{VisualViewport}} that is associated with with <var>target</var>.
1. Otherwise, <a>fire an event</a> named <a event>scroll</a> at <var>target</var>.
1. Empty <var>doc</var>'s <a>pending scroll event targets</a>.

Expand Down Expand Up @@ -1717,13 +1820,15 @@ Otherwise, scrolling is done on an element and let <var>doc</var> be the element
<tr>
<td><dfn event for=Window>resize</dfn>
<td>{{Event}}
<td>{{Window}}
<td>Fired at the {{Window}} when the <a>viewport</a> is resized.
<td>{{Window}}, {{VisualViewport}}
<td>Fired at the {{Window}} when the <a>viewport</a> is resized. Fired at {{VisualViewport}} when the <a>visual viewport</a> is resized
or the <a>layout viewport</a> is scaled.
<tr>
<td><dfn event for="Document, Element">scroll</dfn>
<td>{{Event}}
<td>{{Document}}, elements
<td>Fired at the {{Document}} or element when the <a>viewport</a> or element is scrolled, respectively.
<td>{{Document}}, elements, {{VisualViewport}}
<td>Fired at the {{Document}} or element when the <a>viewport</a> or element is scrolled, respectively. Fired at the {{VisualViewport}}
when the <a>visual viewport</a> is scrolled.
<tr>
<td><dfn event for="Document, Element">scrollend</dfn>
<td>{{Event}}
Expand All @@ -1747,6 +1852,10 @@ Changes {#changes}
This section documents some of the changes between publications of this specification. This section is not exhaustive. Bug fixes and editorial changes are
generally not listed.

<h3 id='changes-from-2022-07-07' class=no-num>Changes From 07 July 2022</h3>
* Introduced the {{VisualViewport}} API and related concepts
* Pinch zoom is now renamed to <a>scale factor</a>

<h3 id='changes-from-2022-06-22' class=no-num>Changes From 22 June 2022</h3>
* Adam Argyle moved the 'scrollend' event from <a href="https://wicg.github.io/overscroll-scrollend-events/">WICG 'overscroll-scrollend-events'</a> to [[CSSOM-VIEW-1]]

Expand Down Expand Up @@ -1785,7 +1894,7 @@ generally not listed.
<h3 id='changes-from-2011-08-04' class=no-num>Changes From 4 August 2011 To 17 December 2013</h3>

* The specification now handles right-to-left and vertical writing modes.
* The specification is now aware of <a>page zoom</a> and <a>pinch zoom</a>.
* The specification is now aware of <a>page zoom</a> and pinch zoom.
* The 'scroll-behavior' CSS property is introduced and scrolling APIs are extended with a mechanism to control smooth scrolling.
* The {{Window/moveTo()}}, {{Window/moveBy()}}, {{Window/resizeTo()}} and {{Window/resizeBy()}} methods are now defined.
* {{Window/innerWidth}} et al now use the WebIDL type {{double}} instead of {{long}}.
Expand Down