Skip to content

Commit

Permalink
Explainers: Document overscroll/rubber banding
Browse files Browse the repository at this point in the history
  • Loading branch information
bramus committed Aug 23, 2022
1 parent 6298d20 commit 421e64d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 6 deletions.
4 changes: 4 additions & 0 deletions explainers/icb.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ When pinch-zooming in the ICB does not get resized because the [Layout Viewport]

See [Virtual Keyboard: Findings](./virtual-keyboard.md#findings).

### Effect of Overscrolling / Bouncy Scroll

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.

### Relation to Viewport Units

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.
Expand Down
7 changes: 7 additions & 0 deletions explainers/layout-viewport.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ When pinch-zooming in the Layout Viewport does not get resized. This is both the

See [Virtual Keyboard: Findings](./virtual-keyboard.md#findings).

### Effect of Overscrolling / Bouncy Scroll

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:

> 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.
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)_. This behavior is not supported by Safari on macOS. Android devices do not support overscrolling, so this updated behavior does not affect them.
### Relation to Viewport Units

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.
Expand Down
8 changes: 4 additions & 4 deletions explainers/scrolling.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
### Dynamic User-Agent UI Elements

@TODO:
### Overscrolling
### Overscrolling and Bounce Scroll

@TODO:
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.

### Bounce Scroll
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.

@TODO:
Overscrolling is [covered in the “CSS Overscroll Behavior Module Level 1” spec](https://drafts.csswg.org/css-overscroll-1/).
4 changes: 4 additions & 0 deletions explainers/viewport-units.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ The value of the `dv*` units are not updated immediately:

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.

### Effect of Overscrolling / Bouncy Scroll

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.

## Issues

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)
77 changes: 75 additions & 2 deletions explainers/visual-viewport.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,70 @@ From [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Visual_Viewport):
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)

```js
@TODO:
let {
width,
height,
scale,
offsetTop,
offsetLeft,
pageLeft,
pageTop,
} = window.visualViewport;
```

These values are:

- `width` / `height` = Width and Height of the Visual Viewport
- `offsetTop` / `offsetLeft` = Distance from edges of the Visual Viewport to edges of the [Layout Viewport](./layout-viewport.md)
- `pageTop` / `pageLeft` = Distance from edges of the Visual Viewport to edges of the [ICB](./icb.md)
- `scale` = The scale factor _(default: `1`)_

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

```js
document.documentElement.style.setProperty('--vvw', `${vvv.width}px`);
document.documentElement.style.setProperty('--vvh', `${vvv.height}px`);
document.documentElement.style.setProperty('--vvpt', `${vvv.pageTop}px`);
document.documentElement.style.setProperty('--vvpl', `${vvv.pageLeft}px`);
document.documentElement.style.setProperty('--vvot', `${vvv.offsetTop}px`);
document.documentElement.style.setProperty('--vvol', `${vvv.offsetLeft}px`);
document.documentElement.style.setProperty('--vvz', vvv.scale);
```

Depending on wether you are using `position: absolute` or `position: fixed`, you need to use these values differently:

```css
#visualviewport {
box-sizing: border-box;
border: 8px solid;
border-image: repeating-linear-gradient(45deg, orange, orange 10px, transparent 10px, transparent 20px) 10;
}

#visualviewport {
position: absolute;
top: var(--vvpt, 0px);
left: var(--vvpl, 0px);
width: var(--vvw, 100%);
height: var(--vvh, 100vh);
}
```

```css
#visualviewport {
box-sizing: border-box;
border: 8px solid;
border-image: repeating-linear-gradient(45deg, orange, orange 10px, transparent 10px, transparent 20px) 10;
}

#visualviewport {
position: fixed;
top: var(--vvot, 0px);
left: var(--vvol, 0px);
width: var(--vvw, 100%);
height: var(--vvh, 100vh);
right: var(--vvol, 0px) + var(--vvw, 0px);
bottom: var(--vvol, 0px) + var(--vvh, 0px);
}
```

👉 Try it out: [Visual Viewport](https://interop-2022-viewport.netlify.app/individual/visual-viewport/)
Expand All @@ -34,4 +97,14 @@ Note that the size of Visual Viewport will be equal to or less than the [Layout

💡 These findings are a textual representation of the [test results table](https://goo.gle/interop-2022-viewport-testresults).

@TODO: iOS vs. Overscrolling
### Effect of Overscrolling / Bouncy Scroll

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)

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.

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

## Issues

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)

0 comments on commit 421e64d

Please sign in to comment.