Warning: Your browser does not support scrollbar-gutter so this demo won’t work.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
100vw position: absolute (???px)
72 |
100lvw position: absolute (???px)
73 |
100svw position: absolute (???px)
74 |
100dvw position: absolute (???px)
75 |
100% position: absolute (???px)
76 |
77 |
78 |
79 |
100vw position: fixed (???px)
80 |
100lvw position: fixed (???px)
81 |
100svw position: fixed (???px)
82 |
100dvw position: fixed (???px)
83 |
100% position: fixed (???px)
84 |
85 |
86 |
87 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/explainers/README.md:
--------------------------------------------------------------------------------
1 | # Interop 2022: Viewport: Explainers
2 |
3 | A collection of explainers covering the key concepts that relate to viewports
4 |
5 | - [Layout Viewport](./layout-viewport.md)
6 | - [Initial Containing Block (ICB)](./icb.md)
7 | - [Visual Viewport](./visual-viewport.md)
8 | - [Virtual Keyboard](./virtual-keyboard.md)
9 | - [Virtual Keyboard API](./virtual-keyboard-api.md)
10 | - [Viewport Units](./viewport-units.md)
11 | - [Scrolling](./scrolling.md)
12 | - [Sizing](./sizing.md)
13 |
14 | These concepts with their visualizations are also covered in [this episode of HTTP 203](https://www.youtube.com/watch?v=xl9R8aTOW_I) _(43:34)_
--------------------------------------------------------------------------------
/explainers/icb.md:
--------------------------------------------------------------------------------
1 | # Initial Containing Block
2 |
3 | ## Definition
4 |
5 | The Initial Containing Block – or ICB for short – is [defined in the CSS2 spec](https://drafts.csswg.org/css2/#containing-block-details):
6 |
7 | > The position and size of an element’s box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block in which the root element[^fn1] lives is a rectangle called the initial containing block.
8 | [^fn1]: Root Element = the `html` element – [DOM Living Standard: The `html` element](https://html.spec.whatwg.org/multipage/semantics.html#the-html-element)
9 |
10 | It takes its size from [the Layout Viewport](./layout-viewport.md) _(for continuous media)_:
11 |
12 | > For continuous media, it has the dimensions of the viewport[^fn2] and is anchored at the canvas origin
13 |
14 | [^fn2]: Back when CSS2 was defined, it had no notion of different viewports. When specs talk about _“the Viewport”_, they mean [the Layout Viewport](./layout-viewport.md).
15 |
16 | ## Visualization
17 |
18 | To visualize it, authors can use this CSS snippet:
19 |
20 | ```css
21 | html {
22 | width: 100%;
23 | height: 100%;
24 | outline: 10px dashed red;
25 | outline-offset: -10px;
26 | }
27 | ```
28 |
29 | 👉 Try it out: [Initial Containing Block (ICB)](https://interop-2022-viewport.netlify.app/individual/icb/)
30 |
31 | ## Measuring the ICB
32 |
33 | To get the actual size of the ICB, authors do not need to size the root element to be `100%` and measure it that way, but can use this JS snippet:
34 |
35 | ```js
36 | document.documentElement.clientWidth;
37 | document.documentElement.clientHeight;
38 | ```
39 |
40 | This due to [an exception in the definition of `clientWidth`/`clientWidth`](https://www.w3.org/TR/cssom-view-1/#dom-element-clientwidth)
41 |
42 | > If the element is the root element and the element’s node document is not in quirks mode […] return the viewport width/height excluding the size of a rendered scroll bar (if any).
43 |
44 | 💡 You might think `window.innerWidth` and `window.innerHeight` might also get you these values, but that’s not the case. Some browsers resize those values as you pinch-zoom in. The values for the `document.documentElement.clientWidth`/`.clientHeight` properties remain stable and are not affected by pinch-zooming.
45 |
46 | ## Findings
47 |
48 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
49 |
50 | ### Size
51 |
52 | In desktop browsers, the ICB – as specced – follows the size of the [Layout Viewport](./layout-viewport.md).
53 |
54 | 
55 |
56 | In mobile browsers the ICB has the same size as the [Layout Viewport](./layout-viewport.md) after initial load which has expanded dynamic UA UI Elements. This is also known as the [Small Viewport](./viewport-units.md).
57 |
58 | 
59 |
60 | There, the pixel width of the ICB is determined by the `viewport` meta tag:
61 |
62 | - `` sizes the width of the ICB in relation to the device’s width
63 | - `` sizes the width of the ICB to the given value, e.g. `2000px`
64 | - Lack of a `` tag makes user agents fall back to a default ICB width of `980px`.
65 |
66 | ### Effect of scrolling
67 |
68 | As specced, the ICB is anchored to the canvas origin on which the document is painted. As a result, the ICB slides out of view as you scroll down a page.
69 |
70 | 
71 | 
72 |
73 | On Mobile, the ICB remains the same size in most browsers, except for a few outliers: they resize the ICB as the UA UI gets hidden. Note that in that case, these browsers do not resize the ICB to match the size of the [Layout Viewport](./layout-viewport.md) but use an in-between value.
74 |
75 | 
76 |
77 | ### Effect of scrollbars
78 |
79 | When operating systems use [Classic Scrollbars](./scrolling.md#classic-scrollbars), the ICB shrinks. This is because those browsers resize the [Layout Viewport](./layout-viewport.md), upon which the ICB size is based. [Overlay Scrollbars](./scrolling.md#overlay-scrollbars) have no effect on the size of the ICB.
80 |
81 | 
82 |
83 | ### Effect of pinch-zoom
84 |
85 | When pinch-zooming in the ICB does not get resized because the [Layout Viewport](./layout-viewport.md) – upon which the ICB size is based – does not resize either.
86 |
87 | 
88 |
89 | ### Effect of the Virtual Keyboard
90 |
91 | See [Virtual Keyboard: Findings](./virtual-keyboard.md#findings).
92 |
93 | ### Effect of Overscrolling / Bouncy Scroll
94 |
95 | When [overscrolling](./scrolling.md#overscrolling-and-rubber-banding) – on platforms that support it - the ICB retains its size and bounces along with the rubber banding as it happens.
96 |
97 | ### Relation to Viewport Units
98 |
99 | Their name might not indicate it, but the [Viewport Units](./viewport-units.md) are sized in relation to [the ICB](./icb.md). See [Viewport Units](./viewport-units.md) for details.
100 |
101 | ## Issues
102 |
103 | We are tracking issues using [the label `ICB`](https://github.com/web-platform-tests/interop-2022-viewport/issues?q=is%3Aissue+label%3AICB)
--------------------------------------------------------------------------------
/explainers/illustrations/icb+layout-viewport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb+layout-viewport.png
--------------------------------------------------------------------------------
/explainers/illustrations/icb-desktop-content-long--classic-scrollbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb-desktop-content-long--classic-scrollbar.png
--------------------------------------------------------------------------------
/explainers/illustrations/icb-desktop-content-long.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb-desktop-content-long.png
--------------------------------------------------------------------------------
/explainers/illustrations/icb-desktop-content-short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb-desktop-content-short.png
--------------------------------------------------------------------------------
/explainers/illustrations/icb-mobile--uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb-mobile--uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/icb-mobile--uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/icb-mobile--uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-desktop-content-long--classic-scrollbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-desktop-content-long--classic-scrollbar.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-desktop-content-long--scrolled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-desktop-content-long--scrolled.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-desktop-content-long.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-desktop-content-long.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-desktop-content-short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-desktop-content-short.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-desktop.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-mobile--uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-mobile--uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/layout-viewport-mobile--uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/layout-viewport-mobile--uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/illustrations/uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-desktop-long-content--classic-scrollbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-desktop-long-content--classic-scrollbar.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-desktop-long-content.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-desktop-long-content.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-desktop.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-dvh--mobilesafari.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-dvh--mobilesafari.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-naming-things.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-naming-things.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--mobilesafari.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--mobilesafari.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-svh+lvh--with-icb--uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-vh--uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-vh--uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/viewport-units-mobile-vh--uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/viewport-units-mobile-vh--uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-api-overlayscontent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-api-overlayscontent.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-api-three-behaviors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-api-three-behaviors.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-everything---offset-layout-viewport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-everything---offset-layout-viewport.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-everything.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-everything.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-icb--with-viewport-units.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-icb--with-viewport-units.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-icb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-icb.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-layout-viewport-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-layout-viewport-1.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus--with-layout-viewport-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus--with-layout-viewport-2.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-focus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-focus.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-nofocus--with-icb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-nofocus--with-icb.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-nofocus--with-layout-viewport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-nofocus--with-layout-viewport.png
--------------------------------------------------------------------------------
/explainers/illustrations/virtual-keyboard-input-nofocus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/virtual-keyboard-input-nofocus.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-1.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-2.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-alt-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-alt-1.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-alt-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-desktop--pinch-zoomed-in-alt-2.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-desktop.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-mobile--pinch-zoomed-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-mobile--pinch-zoomed-in.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-mobile--uaui-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-mobile--uaui-expanded.png
--------------------------------------------------------------------------------
/explainers/illustrations/visual-viewport-mobile--uaui-retracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/illustrations/visual-viewport-mobile--uaui-retracted.png
--------------------------------------------------------------------------------
/explainers/layout-viewport.md:
--------------------------------------------------------------------------------
1 | # The Layout Viewport
2 |
3 | ## Definition
4 |
5 | The Layout Viewport is [defined in the CSS2 spec](https://drafts.csswg.org/css2/#viewport):
6 |
7 | > User agents for continuous media generally offer users a viewport _(a window or other viewing area on the screen)_ through which users consult a document. User agents may change the document’s layout when the viewport is resized _(see the [initial containing block](./icb.md))_.
8 | >
9 | > When the viewport is smaller than the area of the canvas on which the document is rendered, the user agent should offer a scrolling mechanism.
10 | >
11 | > There is at most one viewport per canvas, but user agents may render to more than one canvas (i.e., provide different views of the same document)."
12 |
13 | The [definition on MDN](https://developer.mozilla.org/en-US/docs/Glossary/Layout_viewport) reads:
14 |
15 | > The layout viewport is the viewport into which the browser draws a web page. Essentially, it represents what is available to be seen, while the visual viewport represents what is currently visible on the user's display device.
16 | >
17 | > This becomes important, for example, on mobile devices, where a pinching gesture can usually be used to zoom in and out on a site's contents. The rendered document doesn't change in any way, so the layout viewport remains the same as the user adjusts the zoom level. Instead, the [visual viewport](./visual-viewport.md) is updated to indicate the area of the page that they can see.
18 |
19 | ## Visualization
20 |
21 | To visualize it, authors can inject an empty HTML element and have it positioned against the edges using `position: fixed`:
22 |
23 | ```css
24 | #layoutviewport {
25 | position: fixed;
26 | inset: 0;
27 | outline: 5px dashed var(--blue);
28 | outline-offset: -5px;
29 | }
30 | ```
31 |
32 | 👉 Try it out: [Layout Viewport](https://interop-2022-viewport.netlify.app/individual/layout-viewport/)
33 |
34 | ## Measuring the Layout Viewport
35 |
36 | Using `.getBoundingClientRect()` on the injected `#layoutviewport` element, its size in pixels can be determined:
37 |
38 | ```js
39 | const {
40 | width,
41 | height,
42 | } = document.querySelector("#layoutviewport").getBoundingClientRect();
43 | ```
44 |
45 | 💡 You might think [`window.innerWidth` and `window.innerHeight`](./sizing.md#windowinnerwidth-and-windowinnerheight) might also get you these values, but that’s not the case: Some browsers resize those values as you pinch-zoom in.
46 |
47 | ## Relation to `position: fixed`
48 |
49 | Elements that use `position: fixed`, are layed out against the Layout Viewport, as specified in the [CSS Positioned Layout Module](https://drafts.csswg.org/css-position/#valdef-position-fixed)
50 |
51 | > Same as `absolute`, except the box is positioned and sized relative to a fixed positioning containing block (usually the viewport in continuous media […])
52 | > The box’s position is fixed with respect to this reference rectangle: when attached to the viewport it does not move when the document is scrolled […].
53 |
54 | ## Findings
55 |
56 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
57 |
58 | ### Size
59 |
60 | The Layout Viewport is sized to area through which a user views the document. As you resize the browser, the viewport size is also affected.
61 |
62 | 
63 |
64 | This is also the case on mobile where the browser can expand/contract dynamic UA UI Elements such as address bars and toolbars.
65 |
66 | 
67 |
68 | 
69 |
70 | ### Effect of scrolling
71 |
72 | The Layout Viewport spans the entire viewport and remains in place as you scroll down a page.
73 |
74 | 
75 |
76 | On mobile, browsers contract dynamic UA UI elements as you scroll down a page. These elements can be expanded again as you scroll up. The Layout Viewport follows the size. See visualizations above.
77 |
78 | ### Effect of scrollbars
79 |
80 | When operating systems use [Classic Scrollbars](./scrolling.md#classic-scrollbars), the Layout Viewport shrinks. [Overlay Scrollbars](./scrolling.md#overlay-scrollbars) have no effect on the size of the Layout Viewport.
81 |
82 | 
83 |
84 | ### Effect of pinch-zoom
85 |
86 | When pinch-zooming in the Layout Viewport does not get resized. This is both the case on Desktop and on Mobile.
87 |
88 | 
89 |
90 | ### Effect of the Virtual Keyboard
91 |
92 | See [Virtual Keyboard: Findings](./virtual-keyboard.md#findings).
93 |
94 | ### Effect of Overscrolling / Bouncy Scroll
95 |
96 | When [overscrolling](./scrolling.md#overscrolling-and-rubber-banding), some browsers move the Visual Viewport as it bounces while others do not. A [recent CSSWG Resolution](https://github.com/w3c/csswg-drafts/issues/6299#ref-commit-617c50c) explicitly disallows this behavior:
97 |
98 | > If an element uses [fixed positioning](#relation-to-position-fixed) and is positioned relative to the [initial containing block](./icb.md), or is a sticky positioned element which is currently stuck to the viewport, then when the root scroller experiences "overscroll", that element must not overscroll with the rest of the document’s content; it must instead remain positioned as if the scroller was at its minimum/maximum scroll position, whichever it will return to when the overscroll is finished.
99 |
100 | This behavior newly specced behavior is supported by all WebKit-based browsers on iOS (Safari + Chrome + Edge + Firefox), Firefox on macOS, Chrome on macOS _(with a feature flag)_.
101 |
102 | 👀 See [Recording of Chrome on Desktop](./videos/visual-viewport-desktop-overscroll--chrome.mp4) vs [Recording of Chrome with flag on Desktop](./videos/visual-viewport-desktop-overscroll--chrome-with-flag.mp4)
103 |
104 | This behavior is not supported by Safari on macOS. Android devices do not support overscrolling, so this updated behavior does not affect them.
105 | ### Relation to Viewport Units
106 |
107 | Unlike its name suggest, the [Viewport Units](./viewport-units.md) are not sized in relation to the Layout Viewport. Instead, they are sized in relation to [the ICB](./icb.md). See [Viewport Units](./viewport-units.md) for details.
108 |
109 | ## Issues
110 |
111 | We are tracking issues using [the label `Layout Viewport`](https://github.com/web-platform-tests/interop-2022-viewport/issues?q=is%3Aissue+label%3A%22Layout+Viewport%22)
--------------------------------------------------------------------------------
/explainers/screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-1.jpeg
--------------------------------------------------------------------------------
/explainers/screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-2.jpeg
--------------------------------------------------------------------------------
/explainers/scrolling.md:
--------------------------------------------------------------------------------
1 | # Scrolling
2 |
3 | ## Scrollbars
4 |
5 | As [per CSS2 spec](https://drafts.csswg.org/css2/#viewport):
6 |
7 | > When [the viewport](./layout-viewport.md) is smaller than the area of the canvas on which the document is rendered, the user agent should offer a scrolling mechanism.
8 |
9 | This scrolling mechanism – most of the time – also comes with scrollbars. There are two types of scrollbars we can distinguish:
10 |
11 | 1. Overlay Scrollbars
12 | 2. Classic Scrollbars
13 |
14 | Controlling the visual styling of these scrollbars is defined in the [CSS Scrollbars Styling Module Level 1](https://w3c.github.io/csswg-drafts/css-scrollbars-1/) spec.
15 | ### Overlay Scrollbars
16 |
17 | Overlay Scrollbars are those iOS/macOS-style scrollbars which are placed over the content. They are not shown by default, but only while the user is scrolling. To keep the content underneath visible they are semi-transparent, but that’s totally up to the user-agent (browser) to determine. While interacting with them, their size may also vary.
18 |
19 | 
20 |
21 | ### Classic Scrollbars
22 |
23 | Classic Scrollbars are scrollbars that are placed in a dedicated Scrollbar Gutter. The Scrollbar Gutter is the space between the inner Border Edge and the outer Padding Edge. These scrollbars are usually opaque (not transparent) and take away some space from the adjacent content.
24 |
25 | 
26 |
27 | ## Getting the Scroll Position
28 |
29 | - @TODO: `window.scrollX` / `window.scrollY`
30 | - @TODO: `document.scrollLeft` / `document.scrollTop`
31 |
32 | ## Findings
33 |
34 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
35 |
36 | ### Dynamic User-Agent UI Elements
37 |
38 | @TODO:
39 | ### Overscrolling and Bounce Scroll
40 |
41 | Some browsers support overscrolling the scrollport. When doing this with a swipe gestured, they might bounce back. This behavior is available on macOS, iOS _(and maybe Windows, but that is currently untested)_. Android does not support this.
42 |
43 | Note: When overscrolling slowly at the top edge in Mobile Browsers you might trigger a pull-to-refresh. In this part we are focussing on overscrolling while not triggering pull-to-refresh.
44 |
45 | Overscrolling is [covered in the “CSS Overscroll Behavior Module Level 1” spec](https://drafts.csswg.org/css-overscroll-1/).
--------------------------------------------------------------------------------
/explainers/sizing.md:
--------------------------------------------------------------------------------
1 | # Sizing
2 |
3 | There are various ways to try and read the size of the viewport/window.
4 |
5 | ## `window.innerWidth` and `window.innerHeight`
6 |
7 | ### Definition
8 |
9 | `window.innerWidth` and `window.innerHeight` are defined in the [CSSOM View Module](https://drafts.csswg.org/cssom-view/#dom-window-innerwidth):
10 |
11 | > The `innerWidth` attribute must return the viewport[^fn1] width including the size of a rendered scroll bar (if any), or zero if there is no viewport.
12 | >
13 | > The following snippet shows how to obtain the width of the viewport:
14 | >
15 | > ```js
16 | > var viewportWidth = innerWidth
17 | > ```
18 | >
19 | > The `innerHeight` attribute must return the viewport[^fn1] height including the size of a rendered scroll bar (if any), or zero if there is no viewport.
20 |
21 | [^fn1]: When specs talk about _“the Viewport”_, they mean [the Layout Viewport](./layout-viewport.md).
22 |
23 | ### Findings
24 |
25 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
26 |
27 | In all browsers the `innerHeight` and `innerWidth` behave as defined/expected.
28 |
29 | When pinch-zooming in, WebKit adjusts these values as you pich-zoom in on the page, taking over the `width`/`height` of the [Visual Viewport](./visual-viewport.md)
30 |
31 | ## `window.outerWidth` and `window.outerHeight`
32 |
33 | ### Definition
34 |
35 | `window.outerWidth` and `window.outerHeight` are defined in the [CSSOM View Module](https://drafts.csswg.org/cssom-view/#dom-window-outerwidth):
36 |
37 | > The `outerWidth` attribute must return the width of the client window. If there is no client window this attribute must return zero.
38 | >
39 | > The `outerHeight` attribute must return the height of the client window. If there is no client window this attribute must return zero.
40 |
41 | ### Findings
42 |
43 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
44 |
45 | On Desktop all is pretty straigthforward and the `outerHeight` equals the [`innerHeight`](#windowinnerwidth-and-windowinnerheight) + the size of the browser’s top and bottom bars.
46 |
47 | On Mobile it’s a different story:
48 |
49 | - Only Safari on iOS and Chrome on iOS see the `outerHeight` as the _(unzoomed [^fn1])_ `innerHeight` + size of the browser’s chrome. Essentially this equals the screen’s `height` here, as apps run fullscreen on such devices.
50 | - Most other mobile browsers use the values from `innerHeight` as the value for its `outerHeight`. When the UA UI Toolbars retract, both sizes get adjusted. This seems wrong.
51 | - Firefox on Android does something special where the `outerHeight` is a value somewhere in between the [Small Viewport](./viewport-units.md#the-small-viewport) _(`innerHeight` when UA UI is expanded)_ and [Large Viewport](./viewport-units.md#the-large-viewport) _(`innerHeight` when UA UI is retracted)_.
52 |
53 | [^fn1]: “unzoomed” because `innerHeight` resizes in these browsers. See the section covering [`innerHeight`](#windowinnerwidth-and-windowinnerheight)
54 |
55 | ## `document.documentElement.clientWidth` and `document.documentElement.clientHeight`
56 |
57 | `document.documentElement.clientWidth` and `document.documentElement.clientHeight` can be used to measure the [ICB](./icb.md). This due to [an exception in the definition of `clientWidth`/`clientWidth`](https://www.w3.org/TR/cssom-view-1/#dom-element-clientwidth):
58 |
59 | > If the element is the root element and the element’s node document is not in quirks mode […] return the viewport width/height excluding the size of a rendered scroll bar (if any).
60 |
61 | ## `Element.getBoundingClientRect()`
62 |
63 | If no other way of getting the dimensions of an element is available, [`Element.getBoundingClientRect()`](https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect) can be used.
64 |
65 | > The `getBoundingClientRect()` method, when invoked on an element element, must return the result of getting the bounding box for element.
66 |
67 | Beware that calling this, causes layout _(citation needed)_
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-desktop-overscroll--chrome-with-flag.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-desktop-overscroll--chrome-with-flag.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-desktop-overscroll--chrome.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-desktop-overscroll--chrome.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-desktop-overscroll--firefox.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-desktop-overscroll--firefox.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-desktop-overscroll--safari--different-behaviors.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-desktop-overscroll--safari--different-behaviors.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-desktop-overscroll--safari.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-desktop-overscroll--safari.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-mobile-over-pinch-zoom-out--safari--different-behaviors.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-mobile-over-pinch-zoom-out--safari--different-behaviors.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-mobile-over-pinch-zoom-out--safari.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-mobile-over-pinch-zoom-out--safari.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-mobile-overscroll--safari--different-behaviors.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-mobile-overscroll--safari--different-behaviors.mp4
--------------------------------------------------------------------------------
/explainers/videos/visual-viewport-mobile-overscroll--safari.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-platform-tests/interop-2022-viewport/268dbc7a8e6995f5b78bc0e5fbfbf58539449c14/explainers/videos/visual-viewport-mobile-overscroll--safari.mp4
--------------------------------------------------------------------------------
/explainers/viewport-units.md:
--------------------------------------------------------------------------------
1 | # Viewport-percentage Lengths _(aka “Viewport-relative Units”)_
2 |
3 | ## Definition
4 |
5 | Unlike their name suggest, Viewport Units are **not** based on the size of [the Viewport](./layout-viewport.md) but are based on the size of the [ICB](./icb.md). As per [CSS Values and Units Module Level 4 specification](https://drafts.csswg.org/css-values-4/#viewport-relative-lengths):
6 |
7 | > The viewport-percentage lengths are relative to the size of the initial containing block
8 |
9 | But since [the ICB takes its size from the Layout Viewport](./icb.md#definition) _(for continuous media)_, there is a connection to the Layout Viewport:
10 |
11 | Layout Viewport → Initial Containing Block → Viewport-percentage lengths
12 |
13 | Generally speaking, a Viewport-percentage Length is Equal to 1% of the targeted axis. Its actual pixel value change as the ICB size changes
14 |
15 | > When the height or width of the initial containing block is changed, they are scaled accordingly.
16 |
17 | Taking [the UA-Default Viewport](#ua-default-viewport) as an example, its linked units are:
18 |
19 | - `vw` = 1% of the width of the viewport size
20 | - `vh` = 1% of the height of the viewport size
21 | - `vi` = 1% of the size of the viewport’s inline axis
22 | - `vb` = 1% of the size of the viewport’s block axis
23 | - `vmin` = the smaller of `vw` or `vh`
24 | - `vmax` = the larger of `vw` or `vh`
25 |
26 | ## Visualization
27 |
28 | To visualize the viewport units, we can set an element’s width/height to those units
29 |
30 | ```css
31 | #el {
32 | position: absolute;
33 | top: 0;
34 | left: 0;
35 | width: 100vw;
36 | height: 100vh;
37 |
38 | background: var(--lightblue);
39 | }
40 | ```
41 |
42 | On desktop _(with no scrollbars present)_, it looks like this:
43 |
44 | 
45 |
46 | On mobile, it looks like this:
47 |
48 | 
49 |
50 | To authors this seems weird, but [its behavior is explained below](#size-of-the-ua-default-viewport-on-mobile).
51 |
52 | ## Types of Viewport-percentage Lengths
53 |
54 | Since [the Layout Viewport can change size](./layout-viewport.md#size) as UA UI elements contract or expand, there are different types specific Layout Viewport Sizes that [can be defined](https://drafts.csswg.org/css-values-4/#viewport-relative-lengths).
55 |
56 | 
57 |
58 | Each type of specific Layout Viewport has Viewport-percentage Lengths assigned with it.
59 | ### The Large Viewport
60 |
61 | The Large Viewport is the viewport sized assuming any UA UI Elements that are dynamically expanded and retracted to be *retracted*. It has the `l`-prefix, so its linked units are `lvh` / `lvw` / `lvb` / `lvi` / `lvmin` / `lvmax`.
62 |
63 | > The large viewport-percentage units (`lv*`) are defined with respect to the large viewport size: the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be retracted. This allows authors to size content such that it is guaranteed to fill the viewport, noting that such content might be hidden behind such interfaces when they are expanded.
64 | >
65 | > The sizes of the large viewport-percentage units are fixed (and therefore stable) unless the viewport itself is resized.
66 |
67 | 
68 |
69 | ### The Small Viewport
70 |
71 | The Small Viewport is the viewport sized assuming any UA UI Elements that are dynamically expanded and retracted to be *expanded*. It has the `s`-prefix, so its linked units are `svh` / `svw` / `svb` / `svi` / `svmin` / `svmax`.
72 |
73 | > The small viewport-percentage units (`sv*`) are defined with respect to the small viewport size: the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be expanded. This allows authors to size content such that it can fit within the viewport even when such interfaces are present, noting that such content might not fill the viewport when such interfaces are retracted.
74 | >
75 | > The sizes of the small viewport-percentage units are fixed (and therefore stable) unless the viewport itself is resized.
76 |
77 | 
78 |
79 | ### The Dynamic Viewport
80 |
81 | The Dynamic Viewport is the viewport sized with dynamic consideration of any UA UI Elements. It will automatically adjust itself in response to UA interface elements being shown or not. It has the `d`-prefix.
82 |
83 | > The dynamic viewport-percentage units (`dv*`) are defined with respect to the dynamic viewport size: the viewport sized with dynamic consideration of any UA interfaces that are dynamically expanded and retracted. This allows authors to size content such that it can exactly fit within the viewport whether or not such interfaces are present.
84 | >
85 | > The sizes of the dynamic viewport-percentage units are not stable even while the viewport itself is unchanged. Using these units can cause content to resize e.g. while the user scrolls the page. Depending on usage, this can be disturbing to the user and/or costly in terms of performance.
86 | >
87 | > The UA is not required to animate the dynamic viewport-percentage units while expanding and retracting any relevant interfaces, and may instead calculate the units as if the relevant interface was fully expanded or retracted during the UI animation. (It is recommended that UAs assume the fully-retracted size for this duration.)
88 |
89 | 
90 |
91 | ### UA-default Viewport
92 |
93 | The UA-default Viewport, which for any given document should be equivalent to the large viewport size, small viewport size, or some intermediary size. It has no prefix, so its linked units are `vh` / `vw` / `vb` / `vi` / `vmin` / `vmax`.
94 |
95 | > The UA-default viewport-percentage units (`v*`) are defined with respect to a UA-defined UA-default viewport size, which for any given document should be equivalent to the large viewport size, small viewport size, or some intermediary size.
96 |
97 | ## Findings
98 |
99 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
100 |
101 | ### Effect of scrollbars
102 |
103 | The presence of does not influence the size of the Viewport Units. This per spec:
104 |
105 | > In all cases, scrollbars are assumed not to exist
106 |
107 | When using [Overlay Scrollbars](./scrolling.md#overlay-scrollbars) this is no issue
108 |
109 | 
110 |
111 | However, when using [Classic Scrollbars](./scrolling.md#classic-scrollbars) this becomes an important note to make, as `100vh` and `100vw` grow “too large”. As a result, the UA also needs to add a horizontal scrollbar.
112 |
113 | 
114 |
115 | ### Size of non-UA-default Viewport on Desktop
116 |
117 | As all desktop browsers currently do not have dynamic UA UI elements, they – when the units are supported – size the Small and Large Viewport to the size of the UA-default Viewport.
118 |
119 | ### Size of the Small Viewport
120 |
121 | For all mobile browsers, the Small Viewport size follows the size of the ICB.
122 |
123 | 
124 |
125 | ### Size of the Large Viewport
126 |
127 | For all mobile browsers, the Large Viewport size follows the size of the ICB + size of the dynamic UA UI Elements that have retracted.
128 |
129 | 
130 |
131 | ### Size of the UA-default Viewport on Mobile
132 |
133 | All mobile browsers seem to agree on sizing the UA-default Viewport to the Large Viewport. This explains that why, when giving an element a height of `100vh`, it gets partially obscured by the dynamic UA UI elements:
134 |
135 | 
136 |
137 | 
138 |
139 | ### Size of the Dynamic Viewport
140 |
141 | The size of the Dynamic Viewport adapts itself when the UA UI Elements change.
142 |
143 | The value of the `dv*` units are not updated immediately:
144 |
145 | - When slowly scrolling, some browsers only do this after scrolling for a certain distance, while others respond immediately. The value isn’t updated at 60fps, but is throttled, for performance reasons we can assume
146 | - When swiping over the screen and having the document scroll for a large distance, some browsers do not update the value for `dvh` until the scrolling has stopped
147 |
148 | Some browsers allow the Dynamic Viewport grow larger than the Large Viewport. This is the case when users over pinch-zoom out in all browsers on iOS.
149 |
150 | ### Effect of Overscrolling / Bouncy Scroll
151 |
152 | These units follow the size of the [Layout Viewport](./layout-viewport.md). Since the Layout Viewport’s size is not affected by Overscrolling, these units aren’t either.
153 |
154 | ## Issues
155 |
156 | We are tracking issues using [the label `Viewport Units`](https://github.com/web-platform-tests/interop-2022-viewport/issues?q=is%3Aissue+label%3A%22Viewport+Units%22)
--------------------------------------------------------------------------------
/explainers/virtual-keyboard-api.md:
--------------------------------------------------------------------------------
1 | # The Virtual Keyboard API
2 |
3 | ## Definition
4 |
5 | With the Virtual Keyboard API, authors can get information about the Virtual Keyboard. This is defined in [the Virtual Keyboard API Specification](https://www.w3.org/TR/virtual-keyboard/)
6 |
7 | > The VirtualKeyboard API provides authors with greater control over the visibility of the Virtual Keyboard, and greater ability to adapt the layout of web pages when VK visibility changes
8 |
9 | ## Using the API
10 |
11 | Authors can listen for a `geometrychange` event to get the Virtual Keyboard size.
12 |
13 | ```js
14 | if ("virtualKeyboard" in navigator) {
15 | navigator.virtualKeyboard.addEventListener('geometrychange', () => {
16 | console.log(vk.boundingRect);
17 | });
18 | }
19 | ```
20 |
21 | Additionally they can also trigger it to show or hide.
22 |
23 | ## Overlays Content Mode
24 |
25 | Using the Virtual Keyboard API, authors can change the behavior of the Virtual Keyboard. The only option they have now, is to enable “Overlays Content” mode. This behavior needs to be enabled through JavaScript:
26 |
27 | ```js
28 | if ("virtualKeyboard" in navigator) {
29 | navigator.virtualKeyboard.overlaysContent = true;
30 | }
31 | ```
32 |
33 | Once enabled, this mode does not resize the [Layout Viewport](./layout-viewport.md), [ICB](./icb.md), nor [Visual Viewport](./visual-viewport.md) when the [Virtual Keyboard](./virtual-keyboard.md) is shown.
34 |
35 | 
36 |
37 | ## Browser Support
38 |
39 | The Virtual Keyboard API is only implemented in Chromium-based browsers. Other browser vendors have been asked on their position towards this API:
40 |
41 | - Firefox: [https://github.com/mozilla/standards-positions/issues/531](https://github.com/mozilla/standards-positions/issues/531)
42 | - WebKit: [https://github.com/WebKit/standards-positions/issues/16](https://github.com/WebKit/standards-positions/issues/16)
--------------------------------------------------------------------------------
/explainers/virtual-keyboard.md:
--------------------------------------------------------------------------------
1 | # Virtual Keyboard
2 |
3 | ## Definition
4 |
5 | Devices with a touchscreen mostly offer a On-Screen Keyboard also known as the Virtual Keyboard.
6 |
7 | 
8 |
9 | 
10 |
11 | [The Virtual Keyboard API Specification](https://www.w3.org/TR/virtual-keyboard/) has a section how the Virtual Keyboard affects a browser
12 |
13 | > The Virtual Keyboard (VK) is the on-screen keyboard used for input in scenarios where a hardware keyboard may not be available.
14 | >
15 | > User agents respond to the presence of the VK, without any exposure of this information to web developers in the following way:
16 | >
17 | > 1. Repositioning the user agent above the VK
18 | > 2. Reducing the size of the [layout viewport](./layout-viewport.md) so the VK doesn't occlude it[^fn1]
19 | > 3. Reducing the size of the [visual viewport](./visual-viewport.md) and padding the layout viewport to ensure it can be shifted above the VK[^fn2]
20 |
21 | [^fn1]: This is the current behavior of Chrome on Android
22 | [^fn2]: This is the current behavior of Safari on iOS
23 |
24 | 💡 The [Virtual Keyboard API](./virtual-keyboard-api.md) adds a fourth option to this list of behaviors.
25 |
26 | ## Findings
27 |
28 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
29 |
30 | ### Effect on the Layout Viewport
31 |
32 | The effect of the [Virtual Keyboard](./virtual-keyboard.md) on the [Layout Viewport](./layout-viewport.md) is currently not interoperable, as _some_ browsers resize the Layout Viewport when the Virtual Keyboard gets shown, while others do not resize it.
33 |
34 | 
35 |
36 | Because [`position: fixed` elements are laid out against the Layout Viewport](./layout-viewport.md#relation-to-position-fixed), that might mean that some of those elements get obscured by the keyboard
37 |
38 | 
39 |
40 | This latter behavior might be troublesome if authors want to keep an element positioned against the bottom edge, above the Virtual Keyboard when present.
41 |
42 | 💡 The [Virtual Keyboard API](./virtual-keyboard-api.md) has an option to opt-out of resizing the Layout Viewport in case the Virtual Keyboard is present.
43 | ### Effect on the ICB
44 |
45 | Because the ICB is based on the size of the [Layout Viewport](./layout-viewport.md), browsers that resize the Layout Viewport also resize the ICB.
46 |
47 | 
48 |
49 | This difference in resize-behavior has an effect on [Viewport Units](./viewport-units.md)
50 |
51 | 
52 |
53 | ### Effect on the Visual Viewport
54 |
55 | The Visual Viewport resizes the the Virtual Keyboard gets shown. This is consistent across Mobile Browsers.
56 |
57 | 
58 |
59 | ### Auto-scrolling input elements into view
60 |
61 | When an element that might get obscured by the Virtual Keyboard gains focus, some browsers auto-offset the [Layout Viewport](./layout-viewport.md) so that the input remains in view.
62 |
63 | 
64 |
65 | ## Issues
66 |
67 | We are tracking issues using [the label `Virtual Keyboard`](https://github.com/web-platform-tests/interop-2022-viewport/issues?q=is%3Aissue+label%3A%22Virtual+Keyboard%22)
--------------------------------------------------------------------------------
/explainers/visual-viewport.md:
--------------------------------------------------------------------------------
1 | # The Visual Viewport
2 |
3 | ## Definition
4 |
5 | From [the CSSOM Specification](https://drafts.csswg.org/cssom-view/#visual-viewport)
6 |
7 | > The visual viewport is a kind of viewport whose scrolling area is another viewport, called the layout viewport.
8 | >
9 | > In addition to scrolling, the visual viewport may also apply a scale transform to its layout viewport. This transform is applied to the canvas of the layout viewport and does not affect its internal coordinate space.
10 |
11 | From [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Visual_Viewport):
12 |
13 | > The portion of the viewport that is currently visible is called the visual viewport
14 | >
15 | > The Visual Viewport can be smaller than the layout viewport, such as when the user has pinched-zoomed
16 |
17 | ## Visualization
18 |
19 | To visualize it, authors can get sizing and positioning info of the Visual Viewport through the [Visual Viewport API](https://drafts.csswg.org/cssom-view/#the-visualviewport-interface)
20 |
21 | ```js
22 | let {
23 | width,
24 | height,
25 | scale,
26 | offsetTop,
27 | offsetLeft,
28 | pageLeft,
29 | pageTop,
30 | } = window.visualViewport;
31 | ```
32 |
33 | These values are:
34 |
35 | - `width` / `height` = Width and Height of the Visual Viewport
36 | - `offsetTop` / `offsetLeft` = Distance from edges of the Visual Viewport to edges of the [Layout Viewport](./layout-viewport.md)
37 | - `pageTop` / `pageLeft` = Distance from edges of the Visual Viewport to edges of the [ICB](./icb.md)
38 | - `scale` = The scale factor _(default: `1`)_
39 |
40 | Using a tab more JS, these values can be synced to Custom Properties which you can use to position an element that outlines this Visual Viewport
41 |
42 | ```js
43 | document.documentElement.style.setProperty('--vvw', `${vvv.width}px`);
44 | document.documentElement.style.setProperty('--vvh', `${vvv.height}px`);
45 | document.documentElement.style.setProperty('--vvpt', `${vvv.pageTop}px`);
46 | document.documentElement.style.setProperty('--vvpl', `${vvv.pageLeft}px`);
47 | document.documentElement.style.setProperty('--vvot', `${vvv.offsetTop}px`);
48 | document.documentElement.style.setProperty('--vvol', `${vvv.offsetLeft}px`);
49 | document.documentElement.style.setProperty('--vvz', vvv.scale);
50 | ```
51 |
52 | Depending on wether you are using `position: absolute` or `position: fixed`, you need to use these values differently:
53 |
54 | ```css
55 | #visualviewport {
56 | box-sizing: border-box;
57 | border: 8px solid;
58 | border-image: repeating-linear-gradient(45deg, orange, orange 10px, transparent 10px, transparent 20px) 10;
59 | }
60 |
61 | #visualviewport {
62 | position: absolute;
63 | top: var(--vvpt, 0px);
64 | left: var(--vvpl, 0px);
65 | width: var(--vvw, 100%);
66 | height: var(--vvh, 100vh);
67 | }
68 | ```
69 |
70 | ```css
71 | #visualviewport {
72 | box-sizing: border-box;
73 | border: 8px solid;
74 | border-image: repeating-linear-gradient(45deg, orange, orange 10px, transparent 10px, transparent 20px) 10;
75 | }
76 |
77 | #visualviewport {
78 | position: fixed;
79 | top: var(--vvot, 0px);
80 | left: var(--vvol, 0px);
81 | width: var(--vvw, 100%);
82 | height: var(--vvh, 100vh);
83 | right: var(--vvol, 0px) + var(--vvw, 0px);
84 | bottom: var(--vvol, 0px) + var(--vvh, 0px);
85 | }
86 | ```
87 |
88 | 👉 Try it out: [Visual Viewport](https://interop-2022-viewport.netlify.app/individual/visual-viewport/)
89 |
90 | ## Findings
91 |
92 | 💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).
93 |
94 | ## Size
95 |
96 | As mentioned above, the Visual Viewport API can be used for this. Note that the size of Visual Viewport will be equal to or less than the [Layout Viewport](./layout-viewport.md)
97 |
98 | 
99 | 
100 | 
101 |
102 | ### Effect of scrolling
103 |
104 | The Visual Viewport updates nicely as you scroll and shifts down with the scroll position.
105 |
106 | 
107 |
108 | When UA UI Elements expand/contract is also updates accordingly, except in Edge on Android where there’s a few pixels missing. This bug is corrected as soon as you stop the gesture _(i.e. lift up your finger)_, then the correct values are flushed.
109 |
110 | 
111 | 
112 |
113 | ### Effect of scrollbars
114 |
115 | The presence of [Classic Scrollbars](./scrolling.md#classic-scrollbars) take away space from the Visual Viewport
116 |
117 | ### Effect of pinch-zoom
118 |
119 | The Visual Viewport updates nicely as you pinch zoom
120 |
121 | 
122 |
123 | In Safari on Desktop the values do not update immediately as you pinch-zoom, but are only updated when the gesture is finished _(i.e. lifting up your fingers)_.
124 |
125 | When you over pinch-zooming out in browsers that allow this _(i.e. all based on WebKit)_ something funky happens with the position and dimensions of the Visual Viewport:
126 |
127 | - Its position gets anchored to `0,0` of the canvas. This origin moves between the top-left edge of the [Large and Small Viewport](./viewport-units.md#the-large-viewport) as you move around.
128 | - The `width`/`height` is measured from that `0,0` origin _(which can move)_ to the right/bottom edge of the [Layout Viewport](./layout-viewport.md)
129 |
130 | 👀 See [Screenshot 1 of Safari on iOS](./screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-1.jpeg) and [Screenshot 2 of Safari on iOS](./screenshots/visual-viewport-mobile-safari-over-pinch-zoom-out-2.jpeg)
131 |
132 | 👀 See [Recording of Safari on iOS](./videos/visual-viewport-mobile-over-pinch-zoom-out--safari.mp4)
133 |
134 | ### Effect of the Virtual Keyboard
135 |
136 | See [Virtual Keyboard: Findings](./virtual-keyboard.md#findings).
137 |
138 | ### Effect of Overscrolling / Bouncy Scroll
139 |
140 | When [overscrolling](./scrolling.md#overscrolling-and-rubber-banding), WebKit allows negative values for `window.scrollX` and `window.scrollY`. This is the only engine to expose this. While doing so, the values for the Visual Viewport’s `pageTop` and `pageLeft` also become negative, while its `height` and `width` remain the same size. Because of this, the visualization of the Visual Viewport can get clipped by the [ICB](./icb.md) which [does bounce with the rubber banding effect](./icb.md#effect-of-overscrolling--bouncy-scroll)
141 |
142 | 👀 See [Recording of Safari on Desktop](./videos/visual-viewport-desktop-overscroll--safari.mp4) and [Recording of Safari on iOS](./videos/visual-viewport-mobile-overscroll--safari.mp4)
143 |
144 | Other engines that do not allow negative values for `window.scrollX` and `window.scrollY` as it has a rubber banding effect going on – i.e. Chrome on macOS and Firefox on macOS – follow the same behavior as the [ICB](./icb.md): the bounce with the effect. The values for the `height` and `width` remain the same as it rubber bands.
145 |
146 | 👀 See [Recording of Firefox on Desktop](./videos/visual-viewport-desktop-overscroll--firefox.mp4) and [Recording of Chrome on Desktop](./videos/visual-viewport-desktop-overscroll--chrome.mp4)
147 |
148 | In engines that keep the [Layout Viewport](./layout-viewport.md) in place as the browser rubber bands the values for `offsetTop` and `offsetLeft` remain `0`.
149 |
150 | 👀 See [Recording of Firefox on Desktop](./videos/visual-viewport-desktop-overscroll--firefox.mp4) and [Recording of Chrome with flag on Desktop](./videos/visual-viewport-desktop-overscroll--chrome-with-flag.mp4)
151 |
152 | ## Issues
153 |
154 | We are tracking issues using [the label `Visual Viewport`](https://github.com/web-platform-tests/interop-2022-viewport/issues?q=is%3Aissue+label%3A%22Visual+Viewport%22)
--------------------------------------------------------------------------------