Re: [csswg-drafts] [css-values-4] Add vhc value (#4329)

@frehner said:
> It’s been 5 years that mobile browsers have been doing this. See [#4329 (comment)](https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-542420036)

Thanks for the link.

It looks like this actually landed in [Chrome for Android in version 56](https://www.chromestatus.com/feature/6241601772847104), in [Feb 2017](https://en.wikipedia.org/wiki/Google_Chrome_version_history).

It's interesting to see that the problem with the (then) new design was reported as far back as Feb 2015 on iOS and objected to multiple times by different people and yet there appears to have been and to still be no intent to address these concerns within Safari or any of the other mobile browsers. I'm not sure why it is not seen as a problem that needs addressing. Benjamin Poulain said back in 2015 in defence of problem it created that "This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)" and he also said "For positioning, you can look into "fixed" and "sticky" positinioning. Those two modes creates layers that are composited in real time." So he clearly understood that positioning of content was an issue with the new design, yet missed the point as far as I am concerned. Position fixed and sticky do something different. They take those elements out of the flow. They don't allow you to have a central scrollable region with dynamically determined height, which is what is actually broken. The proposed workaround doesn't help here.

It does look like my team is somewhat late in identifying this problem. I've checked issues surrounding the release in September 2019 of a website using flexbox and a 100vh viewport to position elements at top and bottom with a central scroll. I see that in testing there, we observed that the website was completely broken in Safari on iOS 12 with scroll not functioning at all, but that iOS 13, which had just been released, fixed this. I see that we ended up including `-webkit-overflow-scrolling: touch;` in an attempt to fix that for iOS users that had not yet upgraded to 13. There is no report of this specific issue that I can find though.

Personally, I use Firefox as my primary Android browser and only noticed this with the release of the 'new' [Firefox for Android version 80 in August 2020](https://www.mozilla.org/en-US/firefox/android/80.0/releasenotes/), in which what appears to have been a very poorly tested (not meaning to offend, but that's my experience) bottom url bar feature was introduced as default. Noting that it caused problems on various sites prompted me to check how our own sites fared. That's what has ultimately alerted me to this.

@theres-waldo said:

> > * The size of the additional UI and so remaining available space could depend on user agent/OS font sizes, zoom or accessibility settings, and so `vhc` would change if those change, shrinking if the controls expand. Is that expected/wanted behaviour?
> My understanding of the proposal is that `vhc` would be 1% of the minimum possible viewport size given the _current_ settings. So, if you change the system font size in a way that affects the height of the address bar, the page would be reflowed and `vhc` sizes recomputed. But if you just trigger hiding or showing the address bar through interactions with the page, it would not.

Sure, I understand that. What I was trying to get at, but not very well, is that you could have two different users with the same browser and browser window size, user A and B. User B's browser UI could take up more space (e.g. larger UI for accessibility reasons) and so have a smaller viewport. If the new unit is used to scale content, user B would have their content scaled down more and so be smaller. If that is understood and is accepted behaviour, that is fine. I suppose I don't fully understand what the intent of the new unit is though. If it's to help with scaling then I can't see advantage of it over scaling against the maximum possible viewport size, which is a simpler and better defined concept. If it's to help with positioning content in view, it doesn't since developers can't know which part of the viewport (top or bottom) will be cut off by the browser, based on the browser design and the CSS spec.

@theres-waldo said:

> > * ... and the `viewport` definition makes it clear that this is the area and through which users can interact with the content:  "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."
> 
> Terms that were unambiguous at the time a spec was written can become less clear when the spec is applied in a new context such as mobile browsing.
> 
> "Viewport" is an example of such a term. In mobile browsers, the ability to pinch-zoom the page without reflowing it (which implies pinch-zooming does not change the initial containing block (ICB) from which page elements derive their sizes) has meant that the "viewport" used to derive quantities such as the ICB or scroll positions reported via `window.scrollX/Y` is not necessarily the same as what's currently visible on screen. The [Web Viewports Explainer](https://github.com/bokand/bokand.github.io/blob/master/web_viewports_explainer.md) document provides good background information on this subject.

Thanks for the link. That took me a while to digest and has forced me to think a lot. I understand better what the current draft text is proposing and attempting to achieve in modifying the definition of `vh` to "When user agent chrome does not change size, it is equal to 1% of the height of the initial containing block. When user agent chrome does change size, it is equal to 1% of the height of the initial containing block with the user agent chrome at its smallest size." However, I still don't think it's the right way forward, personally. The definition "Equal to 1% of the height of the initial containing block." is fine as is and does not need modification. The question that needs clarifying is, is a user agent allowed to put 'chrome'/UI on top of the ICB or partially obscure some part of the ICB by shifting it, and do so without modifying viewport-relative units as is currently happening on mobile browsers? If so how and when can they do that?

I've taken a look at how Chrome for Android, Firefox for Android and Firefox for Android Nightly work this evening. I have looked at how they work for two web pages A) and B), and in normal browsing and private browsing modes:

Web Page A) is simply a sufficient quantity of content arranged linearly such that it will overflow the visible viewport:

```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Web Page A</title>
    <style>
* { margin: 0; }
main { background-color: grey; }
header, footer { background-color: green; }
    </style>
  </head>
  <body>
    <header>Header: Start of content</header>
    <main>
      <ol>
        <li>First item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Item</li><li>Last item</li>
      </ol>
    </main>
    <footer>Footer: End of content</footer>
  </body>
</html>
```

Web Page B is a variant on this with a header and footer fixed to the top and bottom of the viewport and a central scrollable region using 100vh and flexbox, which you can [find above in an earlier comment](https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-730549876), and which you can [view for yourself](https://bug1663000.bmoattachments.org/attachment.cgi?id=9187912).

I observed the following:

# Chrome for Android

## Web Page A - Normal Browsing

- Initially: The address bar is shown at the top. The content starts at the bottom of the address bar.
- As I scroll down (swipe up), the address bar immediately slides out the way and the content shifts up.
- I can continue to scroll until I reach the bottom of the content.
- If I scroll back up (swipe down) at any point, the address bar slides back into view.

## Web Page A - Private Browsing

- Initially: The address bar is shown at the top. The content starts at the bottom of the address bar.
- As I scroll down (swipe up), the address bar stays put! **This appears to be a bug in Chrome. It only happens the first time after a page load/reload. Thereafter, if the user scrolls back up and then back down, the address bar starts moving out the way like a normal-browsing window.**
- I can continue to scroll until I reach the bottom of the content.

## Web Page B - Normal Browsing

- Initially: The address bar is shown at the top. The fixed header is positioned at the bottom of the address bar. The fixed footer is nowhere to be seen. It's cut off the bottom. A user would not know that it even existed in this case.
- As I scroll down (swipe up), **the address bar stays put** and the central region scrolls **with the footer remaining cut off**.
- If I scroll back up (swipe down) at any point, this simply changes the scroll position and does not affect the address bar.
- As I reach the bottom of the central region, the address bar starts to disappear off the top of the of the window and the entire content shifts up with it to eventually reveal the footer.
- Now, if I wish to reveal the address bar, I have to scroll the entire way back to the top of the list. Then, if I scroll more, everything shifts down and only then is the address bar revealed.

## Web Page B - Private Browsing

- Same as normal browsing.

## Comment on Chrome for Android behaviour

- Behaviour for Web Page A is acceptable to me.
     - The ICB is the size of the viewport without the address bar.
     - The "viewport" has the same size as the ICB (as per spec), but is initially positioned such that the bottom of it is cut off. However, this is only temporary: The ICB (and hence full viewport) shifts back into view as soon as the user starts interacting with the page by scrolling. Thus, the entirety of the viewport is visible most of the time.
     - An alternative would have been to keep the viewport in the same position as the ICB and as if the address bar was not there. The address bar would initially be rendered on top of the viewport, but would move out the way quickly (e.g. after a short period of time, or if the user starts interacting with the content, such as by touching/scrolling as [described above](https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-730549876) ).
    - There appears to be a bug in the address bar hide/reveal in private browsing.

- Behaviour for Web Page B is not acceptable to me.
    - The address bar does not get out the way, and so what should be the visible viewport is truncated the majority of the time.
    - If the behaviour was adjusted so that the address bar moved out the way as soon as the user started to scroll, just like for Web Page A, the problem would be adequately addressed. It seems inconsistent that Web Page A and Web Page B behave differently with regards to scroll and address bar hiding. I cannot think of any obvious technical reason why Chrome (or any other browser) would not be able to implement that. If that was fixed, then we would be in a situation whereby the visible viewport was only briefly and temporarily obscured/truncated again. (Hence my [proposal to explicitly allow temporarily overlaying or truncating the viewport](https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-731476294).)
    - If that could not be done for whatever reason, then in this case, because the address bar does not get out of the way and is a (semi-)permanent feature, viewport = ICB ought to be taken as the visible area with the address bar shown. That would avoid content that should be visible being cut off. 
    
# Firefox for Android

## Web Page A - Normal Browsing

- Initially: The address bar is shown at the bottom. The content starts at the top app window.
- As I scroll down (swipe up), the address bar immediately slides out the way.
- I can scroll until I reach the bottom of the content.
- If I scroll back up (swipe down) at any point, the address bar slides back into view.

## Web Page A - Private Browsing

- Same as normal browsing.

## Web Page B - Normal Browsing

- Initially: The address bar is shown at the bottom. The fixed header is positioned at the top of the app window. The fixed footer is nowhere to be seen. It's cut off the bottom. A user would not know that it existed.
- As I scroll down (swipe up), **the address bar stays put** and the central region scrolls **with the footer remaining cut off**.
- I can never reveal the bottom of the list in the central region, nor the bottom footer. The scroll hits a buffer and doesn't permit me to.
- If I scroll back up (swipe down) at any point, this simply changes the scroll position.

## Web Page B - Private Browsing

- Same as normal browsing.

## Comment on Firefox for Android behaviour

- Same issues with Firefox as with Chrome. For web page B, the address bar doesn't get out the way, resulting in what should be the visible viewport being truncated most, if not all the time.
- There is also a bug with scroll that is only partially addressed in Firefox Nightly. In the current Firefox nightly, you get as far as you can scroll, which still has content hidden under the address bar. Then, if you attempt to scroll some more the address bar drops away only to reveal that the viewport is off the bottom of the window, with white space underneath. This has already been reported. Also, sometimes the scroll gets stuck and you can't scroll back up. That too has been reported.

I'll leave Safari on iOS as an exercise for the reader!

I hope this helps understand why I [proposed above](https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-731476294), to keep the current definition of `vh`, but add a clarification that it is acceptable for user agents to overlay/obscure/truncate part of the visible viewport, provided it is only temporary and brief and for a specific reason. It normalises the good bits of current mobile browser design (e.g. how web page A behaves), while forbidding the bad bits (how web page B currently behaves) without requiring a change to the current definition of `vh`. I've tried to improve/simplify my previous text here:

> The user agent may either a) overlay the viewport or b) shift the viewport such that part of it is obscured without altering viewport-relative units, provided that it is:
> * associated with the display of additional user interface required to undertake a specific action, such as a keyboard when assistance with form input is required or an address bar when the user needs to navigate or to a new location, and
> * temporary by design such that:
>     * the user interface only appears when required or requested by the user, and
>     * the additional user interface is removed when the user completes the action, dismisses it or undertakes an unrelated action.
> 
> Any other change to the visible viewport must result in a corresponding change of relative-viewport units.


-- 
GitHub Notification of comment by mind-bending-forks
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-731897172 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Monday, 23 November 2020 02:32:15 UTC