Closed frehner closed 3 years ago
Is there anything that needs to be done for this to move to the next step?
I've created an initial proposal PR to add this to the spec. See #5108 :)
Today, I happened to realize that the new vhc unit value might not be what web developers want in cases where visualViewport.scale != 1.0
. I am assuming that the vhc unit value is static even if users zoom in/out the site in question, but the vhc unit value should be changed in response to the visualViewport scale value?
Doesn't that create a bit of circularity? The initial viewport scale gets chosen based on the width of the contents of the page right? If we make the contents on the page depend on the visual viewport scale, that seems bad.
Today, I happened to realize that the new vhc unit value might not be what web developers want in cases where
visualViewport.scale != 1.0
. I am assuming that the vhc unit value is static even if users zoom in/out the site in question, but the vhc unit value should be changed in response to the visualViewport scale value?
Vhc should act exactly how vh currently acts, I believe.
Emilio is right. It will introduce a bad circular referencing thingie. So we should NOT do that. What I am still wondering is that what the vhc value should be on sites where minimum-scale size is applied. Here is an example (which is based on http://bokand.github.io/demo/urlbarsize.html) that the minimum scale is 0.5. In this case, vhc unit value should be ''ICB height + user agent chrome's height / 0.5"? I am supposing that's what web developers want.
Assuming I'm understanding you correctly (and I'm not sure that I am, so sorry about that) -
I am supposing that's what web developers want.
While what you're proposing may be something developers want, I don't think it is related to the vhc
unit discussed here and would potentially be a different unit. There was already some discussion about whether vhc
should change with visual viewport during one of the WG meetings (e.g. this one has some I believe) and it was decided (and I agree) that the vhc
unit should just behave exactly as the vh
unit, with the only difference being the values that they're computed out to be when UAC could change size (e.g. mobile devices).
I do think there is value in potentially exploring other units (or environment variables as was mentioned in that meeting's minutes) in a separate proposal as well though.
Hopefully I've understood what you're talking about. My apologies if I haven't though.
ooh, you are right. I was confused by the name vhc
, I somehow thought it contains the browser chrome's height even if the chrome is hidden. So my question is more about on vh units and it seems Chrome and Firefox don't factor 0.5 in vh units in the example case. :)
I am sorry for the confusion.
I don't know whether y'all are still looking for names, but I might suggest vvh
for "visual viewport height." It would accord with the visualViewport
DOM API that way. Just a thought.
Another workaround/package has been created to solve this issue in the meantime... :)
https://twitter.com/sitnikcode/status/1288097180721377280?s=20
What are the next steps here? What more can I do to get this moving? I've created a PR in hopes that would help, but it appears that has stalled as well.
Can someone direct me as to what I can do to get this done?
Curious if folks here think there's room for a max complimentary unit, since vhc
is a lot like a min/safe viewport unit? A unit for the safe viewport, the ~viewport, and a max viewport. This could help answer what is "fullscreen" vs "filling the viewport", which I believe is part of what this unit seeks to remedy.
fullscreen (aka viewport including OS chrome/insets/cutouts/etc)
> viewport
> viewport excluding chrome
👇
vhmax
> vh
> vhmin
On desktops vh
, vhmin
/vhc
likely resolve to the same value, but on mobile, they offer an escape or more precise intent. A vhmax
unit though might/should report different on desktop vs mobile, as the maximum viewport potential isnt the same as the root viewport. DOM, games, etc could prepare views for fullscreen with this unit, as opposed to preparing for full viewport.
Thoughts?
Another thing I'd like to see if a vhc
unit can remedy / pacify is how zooming effects the viewport unit. Perhaps this vhc
or vhmin
unit (which intends to be a "safe" viewport unit), is additionally safer by representing the original viewport. Zooming the page changes the viewport unit today, and I'd like to see this new unit NOT be affected by zooming. Instead it could represent the viewport size in its natural / original size. Making it slightly more reliable in regards to a value that's the visual original safe sized viewport, and not a potentially super zoomed slim amount of space.
It appears I'm arriving at this a bit late. I'm interested in this because I work at a company where, amongst other things, we develop mainly non-public web applications for our clients. We commonly make use on what is sometimes referred to as the holy grail layout, having:
Two public examples are:
This used to be difficult to achieve without various hacks or javascript until the vh
unit and flexbox
arrived and made it all easy. The fixed header and footer could then be achieved using vh
and flexbox
with some simple HTML like this:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>test flex fixed header & footer</title>
<style>
* { margin: 0; }
body { height: 100vh; flex-direction: column; display: flex; }
main { height: 100%; overflow-y: scroll; background-color: grey; }
header, footer { background-color: green; }
</style>
</head>
<body>
<header>Header: Always visible at the top</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: Always visible at the bottom</footer>
</body>
</html>
Just over a year ago we had several web applications using this technique, working consistently across desktop and mobile... and then they broke on mobile only. The bottom of the page (sometimes just the footer, sometimes the footer and then some, sometimes part of the footer and also action buttons that had been positioned for easy access by fingers on mobile at the bottom of the page using position: sticky; bottom: 0
) was cut-off, hidden under part of the browser UI. Worse, these parts of the web application sometimes couldn't be accessed at all unless the user scrolled right down to the bottom of the central region, and then in some cases, could simply not be accessed at all. The fact that these applications now behave differently on desktop and on mobile, meaning that we will now potentially have to detect mobile vs desktop and do something different on each is a real pain. I had thought those days of being force to do device type/user-agent probing or of needing to use javascript to acheve simple goals, like a basic layout with elements fixed to the top and bottom of the viewport, were long gone - but apparently not, and that's incredibly frustrating.
I started filing various bugs against Firefox for Android, this having the worst behaviour and apparently being the most buggy, but have ended up here. Having read through everything that's gone on, and what is proposed... I'm a bit shocked to be honest.
There's a lot to get a grip on, but my understanding of what has gone on at high level is as follows:
vh
as a unit or a concept. vh
is not the problem here. Changing the viewport size while scrolling; that is, the particular chosen design of the hiding address bar feature, is the problem. However, it was decided to blame and, worse re-interpret vh
instead, breaking websites in the process. I've looked at the standard, and I've read comments along the lines of vh
being defined in an ambiguous way anyway, but I don't agree that that's the case. It clearly links it to the size of the viewport (which, by definition, is the what is visible) and says that it should change when the viewport changes.vh
in the spec.vh
again, thus potentially not just breaking sites on mobile but on desktop too. Isn't that a problem for anyone? It is for me. Furthermore, this proposal doesn't even solve the problem: My understanding is that, for my simple example above, it will either lead to websites with content that is cut off or content that is unnecessarily smaller than the viewpoint most of the time on mobile. So, rather than having an extremely broken solution, as a developer, I've got the choice between two badly broken solutions.So, rather than simply complaining, I'd like to go back to the root of the problem and try to propose an alternative.
The problem is with:
vh
is calculated based on a something that is NOT actually the visible viewport as required by its definition, most of the time.So let's start by banning that simultaneous scroll and changing of the viewport size by sliding some toolbar into or out of view. If a toolbar is in the process of being slid into or out of view when the user starts to scroll, pause that while the user scrolls, and then continue it when they are done.
So, now we are left with two challenges: How can we hide the address bar when not needed? How can we show the address bar when needed? We need to do this in a way that leaves the definition of vh
in tact most, if not all of the time.
There are various possibilities here, and I don't think it would matter too much if different browsers choose different approaches. Some possibilities I can think of are:
At present, scrolling in the reverse direction is used as a trigger for re-showing the address bar. That will need to change. Here, I think it would be helpful if there could be a consistent approach across all browsers to the gesture for achieving this. I don't know what the best approach is, but possibilities include:
In terms of the viewport, the address bar could slide over it, noting that this is only a temporarily infringement (like a temporary keyboard/form input control might), or it could cause the viewport to shrink in size (change in vh
).
If the user calls up the address bar, but then chooses not to interact with it for some period of time, it could be re-hidden. Whether or not this results in a recorded change in vh
will depend on what the browser has decided to do when showing the address bar. I don't think it's critical either way provided the default is for the address bar to be hidden and it's appearance is only fleeting/temporary. (Whereas, at present, you typically have to scroll down the the very bottom of all content, and then some, to be able to reveal content that should always be in view.)
I believe that if browsers take an approach like described above, the problem can be considered fully addressed:
vh
behaves as defined by the spec, either with possible minor short-lived infringements only during a transitions or with a changing viewport size (but not at the same time as user scrolling), depending on exact implementationvh
and flexbox
to position items at top and/or bottom with central scrollable region for both mobile and desktop once again!vh
unit changing at all due to address bar movements, with the compromise being that some content will be hidden when the address bar is in place - but only temporarily and briefly, and will be exposed or slide back into view when it gets out the way.So in this case, I suppose I am saying that I think that browsers should adjust the design of the address bar hiding feature to comply with the CSS spec in a way that provides a good user experience, not the spec being broken to support questionable browser design choices and poor user experience. (If that can't be done in a way that is good for user experience, then perhaps hiding address bars will have to be disabled until such time that CSS provides some new functionality to make it work well - but I don't think this proposal is it, and I think the the proposed solution above can be made to work adequately.)
As such, you could argue that this proposed change to the CSS spec is perhaps no longer required. I think there is still merit in an additional vhmax
unit though, which would be based on the maximum size the viewport could have (i.e. with hide-able toolbars hidden). If you want to scale font-sizes, then you would probably want that to be relative to browser window size and may not wish that to be sensitive to minor changes in viewport size which you could get with vh
(depending on browser implementation of the address bar hiding). vhmax
would give you that.
Whatever is ultimately decided, please don't redefine vh
and further break backwards compatibility. Keep vh
as is so that websites like ours with elements pinned to the top and bottom are not broken and a central scroll region are not broken, and add new units if that helps.
Thank you.
That was a very long post which not everyone will want or have the time to read, so let me try to capture it in a nutshell:
The key thing I am unhappy about is that design of the hiding address bar feature combined with the way scroll works on mobile browsers means that, for mobile browsers only, sites using vh
and flexbox
like this will have an important part of the viewport cut off for for pretty much the user's whole journey with the page. They only get to see and interact with the whole thing if they scroll right to the very end of the scrollable content and then some.
So, what I'd ideally like:
So, I'd like a clear statement from here that any browser design that results in the some of the defined viewport being cut off pretty much all of the time, and thus resulting in a different experience across desktop and mobile, is non-standard conforming and needs to be fixed. Breaking websites in such a way should not be an accepted outcome of this proposal.
I'm not sure where or why you've come to the conclusion that "breaking websites in such a way" is a desired outcome of this proposal. I've acknowledged in this proposal that the current behavior is not ideal, and my intent with this proposal is to provide a hopefully simple-to-implement-by-browsers workaround for how things currently are (with the goal that it could get released sooner rather than later........) This proposal, for better or worse, doesn't change the current behavior of vh
- it is meant to provide a workaround/new option by way of a new unit.
I have been told WONT FIX with a link to this issue.
It seems to me from that bug report that this wasn't linked to as a solution to your problem, but as a see also to your problem; in other words, perhaps this proposal could help you in the meantime (if it's accepted/implemented).
That said, I would love for an additional proposal to be created that addresses the root cause and gets browsers to conform to it; I would fully support it (not that my support means much 🙂 ).
Thanks @frehner.
in other words, perhaps this proposal could help you in the meantime (if it's accepted/implemented).
I appreciate your efforts. Unfortunately ~this proposal~ the proposed vhc
unit won't help our particular case.
I'm new here and not familiar with the CSS spec process. Please can you point me to the full specification of exactly what this proposal is, so that I am not talking at cross purposes? Is it literally just what is said in the Proposal section of https://github.com/w3c/csswg-drafts/issues/4329#issue-495372962, that is, to introduce a new unit, vhc
that is based on the minimum possible viewport size, or is it more than that? Earlier comments in the thread give the distinct impression that vh
itself was being changed or being considered for change too.
Also, we initially raised an issue about the breakage in Firefox for Android, and were told that it would be addressed by this issue, but then that issue was subsequently closed without fixing the breakage. When we commented on the closure, we were pointed to a document that indicates that Safari, Firefox and Chrome mobile browsers are now all taking the definition of vh
to be "relative to the largest possible viewable area" (rather than as per the CSS spec). When we complained about that we were told:
If you want to change the
vh
unit behavior, you should open a spec issue in https://github.com/w3c/csswg-drafts instead.
which led us to believe that vh
had or was already being redefined in the standard to be "relative to the largest possible viewable area" and that we would need to open a spec issue if we wanted to change it back. We were also told:
There is an ongoing discussion to change the spec description about
vh
units and introduce a new CSS unit which is not including dynamic toolbar height, it's https://github.com/w3c/csswg-drafts/issues/4329
Again, we read this as two things: a) change the spec description about vh
and b) introduce a new CSS unit.
We were also asked to file new issues in against Firefox for the problems that had not been addressed, one of which was the specific breakage I have been referring to. That was then marked as WONT FIX though with a link to this thread.
So, we understood (perhaps misunderstood) that this thread and associated proposed changes to the CSS spec were being:
vh
unit was being suggested for modification here too... (with earlier comments in the thread talking about how vh
can be changed to make it useful etc.)So:
vh
in the spec is not actually being changed, then I'm not sure that I need to file a proposal here. If it is agreed that vh
is intended to be relative to the "visible" viewport size, then mobile browsers are currently not respecting that. It would seem that I need to file new issues on Firefox, Safari and Android requesting that they change the way they work to be compatible with the spec. and so my proposal needs to be sent to them (in triplicate?) instead.vh
is being considered for change within the CSS spec (for example, to mean "relative to the largest possible viewable area"), either here or in some other proposal, then please can someone point me to that, so that I can comment there?Thanks.
- If the definition of
vh
is being considered for change within the CSS spec (for example, to mean "relative to the largest possible viewable area"), either here or in some other proposal, then please can someone point me to that, so that I can comment there?
I think of this as less a change, and more a clarification, to reflect existing practice of how browsers are already interpreting vh
on mobile platforms. I do think it's important that this clarification be made, to avoid confusion, and the work-in-progress PR for this issue does contain wording that includes this clarification.
- If the definition of
vh
is being considered for change within the CSS spec (for example, to mean "relative to the largest possible viewable area"), either here or in some other proposal, then please can someone point me to that, so that I can comment there?I think of this as less a change, and more a clarification, to reflect existing practice of how browsers are already interpreting
vh
on mobile platforms. I do think it's important that this clarification be made, to avoid confusion, and the work-in-progress PR for this issue does contain wording that includes this clarification.
To be clear, I added that but it doesn’t have to be there - it wasn’t discussed as part of this proposal so it could be removed.
I think a clarification, whether that be here or in a separate proposal for change to the spec. would be helpful. I would propose something different to the modification that @frehner has already started drafting though. Maybe something like this at some appropriate point in the spec.:
On occasion, the user agent may need to change the area available for the display of content. If that change 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 is also
- 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,
then it is at the discretion of the user agent as to whether that constitutes either
- an overlay (with no change to
vh
orvw
), or- a change of the viewport area (with corresponding reduction in
vh
orvw
).Any other change of the area within which content is displayed must be interpreted by the user agent as a change in the viewport.
I hope that this would make it clear that the current situation on mobile browsers, whereby an address bar is present at a point when the user has not requested it causing the content to be pushed down and the viewport to be truncated at the bottom, and this state persisting until the user has scrolled right to the bottom of the scrollable content and then a bit more before the address bar finally moves out the way and full viewport finally becomes visible, is not compatible with the standard and so is not acceptable browser/user agent design: It fails the criterion that the additional user interface (address bar) is only presented when required or when requested, and it fails the criterion that it is gets out the way as soon as it is not needed any more. It means browsers will have to change the design of that feature (address bar scroll bar interaction) or keep the feature but alter (fix) vh
to be compatible with the actual viewport again.
Regarding this proposal for a new unit representing 1% of the "minimum possible" viewport size, is it a well-defined/workable/future-proof concept in general terms? I'm not sure that it is. (I've edited this to clarify concerns...)
vhc
would change if those change, shrinking if the controls expand. Is that expected/wanted behaviour?vhc
in that browser would unexpectedly look different because the minimum theoretical size has changed, even though that new control would not be visible most of the time?So, if a new unit is to be added to the spec, I would suggest that it represent "1% of the maximum possible viewport size" instead, which is a much more clearly defined (and understood I think) quantity, since any user agent will place the viewport within some kind of container that has limits on its size. On desktop browsers, where users can choose to display or hide various display toolbars, status bars etc. this will be relative to the maximum viewport size they could theoretically achieve by hiding them all. The key thing is that it would scale with the user agent container/browser window, and would not change when the viewport changes size due to changes in the user agent interface, and so would be suitable for scaling fonts etc. (regardless of how browsers choose to interpret vh
).
With the changes above (clarification and different new unit):
vhmax
or "1% of the maximum possible viewport size" unit would be suitable for scaling fonts/content, andvh
unit would - once again I hope - be suitable for positioning content.
- If the definition of
vh
is being considered for change within the CSS spec (for example, to mean "relative to the largest possible viewable area"), either here or in some other proposal, then please can someone point me to that, so that I can comment there?I think of this as less a change, and more a clarification, to reflect existing practice of how browsers are already interpreting
vh
on mobile platforms.
I'd like to challenge the point about this being a clarification not a change. About a year to a year and a half ago, all browsers, including mobile browsers, were interpreting vh
as being relative to the visible viewport. This was its initial definition back in 2005, was also its defintion in the first candidate recommendation back in 2012 and remains its unambiguous definition in the CSS current spec:
initial containing block
: https://www.w3.org/TR/css-values-3/#viewport-relative-lengthsinitial containing block
links this to the viewport
, "For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin; it is the page area for paged media." https://www.w3.org/TR/CSS21/visudet.html#containing-block-detailsviewport
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."From the moment vh
became widely available in browsers, content creators (like ourselves) were using it for both positioning and scaling content. Then, in the past year and a bit mobile browsers, wanting to implement hiding toolbars, found that their chosen design didn't provide a good user experience. Instead of changing the design to fix it, they took a wrong turn and decided to reinterpret vh
to be the maximum possible viewport size instead in an attempt to patch the problem. However, this patch had the unintended consequence of breaking websites like our own that were using vh
for positioning of content within the visible viewport. The current draft of this proposal unnecessarily (and unacceptably in my view) formalises a change of the definition of vh
from "relative to the viewport area (the viewport being what you can see and interact with)" to "relative to the maximum possible viewport area". It is therefore accepting a backwards incompatible change that results in breakage for websites that have been using the current definition of vh
- which has been in the spec in some form for 15 years. The current draft text definitely represents a change and not a clarification, since it changes the way that some websites using vh
function in such a way that they are broken.
The wrong turn that mobile browsers have made is relatively recent in the grand scheme of things and I observe that the design of such features is still in flux, and so it can be fixed/undone/improved. So I don't see any need to change the spec with regards to vh
meaning the visible viewport. However, clarification on how browsers should handle changes in the visible viewport due to additional toolbars and whatnot and giving some leeway for brief/temporary overlays, as per my previous post, would be useful, I think and would hopefully allow browsers to update their design in a way that is good for user experience and content creators alike.
It’s been 5 years that mobile browsers have been doing this. See https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-542420036
Regarding this proposal for a new unit representing 1% of the "minimum possible" viewport size, is it a well-defined/workable/future-proof concept in general terms? I'm not sure that it is. (I've edited this to clarify concerns...)
How will a user agent know in advance whether the user will call up an address bar or a small or large keyboard or other control, each of which could have a different size? Does the user agent need to choose the smallest possible area based on all possible 'overlays' to be on the safe side?
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?What happens in future if a browser decides to let the user slide the address bar out even further to expose some other control such that the minimum size shrinks? Does that mean that any web content using
vhc
in that browser would unexpectedly look different because the minimum theoretical size has changed, even though that new control would not be visible most of the time?
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.
- ... 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 document provides good background information on this subject.
@frehner said:
It’s been 5 years that mobile browsers have been doing this. See #4329 (comment)
Thanks for the link.
It looks like this actually landed in Chrome for Android in version 56, in Feb 2017.
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, 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 thatvhc
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 andvhc
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 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:
<!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, and which you can view for yourself.
I observed the following:
Behaviour for Web Page A is acceptable to me.
Behaviour for Web Page B is not acceptable to me.
I'll leave Safari on iOS as an exercise for the reader!
I hope this helps understand why I proposed above, 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 visible viewport or b) shift the ICB such that part of the visible viewport is obscured without altering viewport-percentage length units, provided that the change 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 ICB or visible viewport must result in a corresponding change of viewport-percentage length units.
Thank you for having this discussion. I don't have anything to add. I just appreciate that some do.
It would be good to have some feedback on my input to this thread, so I/we know what to do from here. @frehner said back in October 2019 that "if someone comes up with a solution that makes the vh unit itself useful again I would be all for it!". I've made a suggestion to allow but clarify when/how the viewport/ICB can be overlaid/obscured/cut-off by the user agent. Let's call it the obscured viewport clarification suggestion for brevity. With my suggestion, browsers are guided to avoid designs that obscure/truncate/overlay what would ordinarily (e.g. without zoom) be the visible viewport unless it is temporary and for a specific purpose. This hopefully makes vh
useful again for developers who wish to use it to position content, while accepting that it may be obscured on occasion by the user agent, but only temporarily/briefly. This therefore requires improvement to current mobile browser design, which, as per my previous post, sometimes leaves content cut off most of the time and without good reason. So:
vh
that it does not address?vh
, especially noting that this proposal has already been approved? Various possibilities I can think of are:
vh
are incompatible across the two proposals.vh
. I make a new 'obscured viewport clarification' proposal.I'd also like to add that @frehner's recent thread on twitter was brought to my attention and I note that I also made several posts on here on the same day. I also note that my colleagues reviewed my first post on this thread before I posted it, and they provided feedback along the lines of "it's fair but very direct/blunt in places" and I acknowledge that I can be overly direct and blunt! So, for the record, while I don't believe I've been in any way aggressive, if I've been overly blunt/direct or just wrong about anything and caused any offence, I apologise. Also, feel free to correct me if you think I've got anything wrong. Thanks.
I've observed this thread for the last week or so - things seem to have gotten weird. Your posts, @mind-bending-forks, started with indignation that browser standards didn't bend to your will or solve your problems. The sheer length of your posts makes things a bit weird because almost nobody will take the time to read them, and they don't seem to contribute to a healthy discussion about the original topic. Looking up @frehner's tweets and then posting the tweets here is quite unusual, and almost seemed like harassment to me. I think that the best path forward is to let the discussion here calm and shift back to its original topic - if it doesn't solve your problems then you can make separate proposals. I don't think this issue is the place where you'll find your answers.
@joeldenning You are entitled to your opinion that my contributions to this thread are weird, unusual and not conducive to a healthy discussion. However, I take exception to the suggestion that I have harassed or almost harassed anyone. I haven't.
If anyone would like to take the time to read and evaluate what I have contributed, which I believe to be relevant and on topic, and to engage with me on a technical level about it, then I would be happy to do so. In the meantime, I'll be taking @frehner's advice and taking a break from this for a while. Thank you.
@mind-bending-forks
As I'm not a member of the w3c, I have no idea what would be better - if you were to create a new proposal and try to get the w3c's attention in that way, or having the conversation here. I personally am open to either way and will follow the conversation wherever it is (if you make a new issue, please link it here so I can follow it!)
In any case, no matter what happens, may I suggest something that may help your proposal a bit? (again, as I'm not a member of the w3c, I can't guarantee anything, but I hope that my suggestion can help your ideas progress)
Perhaps you could follow the template I used for my first post here for your proposal? If you were to do it that way, it makes it easier for anyone to drop in, take a look at what's being proposed, and comment on it - even if they haven't been following the conversation so far. I think that would increase the chances that it gets discussed.
It may help to take some time on it too - write it down, wait some time, and proof read it / clean it up. I did that 3/4 times on each of my proposals and I find it has really helped me cement what I'm proposing and what's just superfluous and can be removed.
Maybe you could even include another section that talks about how it may affect websites that (for better or worse) expect the current behavior of vh
and if they would need to be changed in any way - it's always good to be thinking about how a proposal may affect existing websites, even if you're correcting a bug. (see Javascript's typeof null
for reference haha)
Anyway, again, you don't need to do that. I just have found some measure of success by doing it that way and I would love to understand your proposal - and see it get commented on.
Sidenote: regarding my tweets you referenced earlier, it's unfortunate that you came away with the impression that I was directing them at you. For clarity, I wasn't, though the timing of it may have appeared that way. In any case, I hope we can move on from that discussion and just focus on the proposal here. 🙂
@frehner Thank you very much. I really appreciate this excellent advice.
As it turns out, last weekend I started drafting an article, attempting to draw together what I have come to understand - which is still evolving - into something that is hopefully more coherent and easy to follow than the disparate posts I have made in this thread. It currently has sections on:
One of my colleagues has provided feedback on an initial draft already. Pulling it together like that has been a good experience for me so far. Your suggestion to cover how the new proposal may affect websites - for better or for worse, is a good one, and this is something I think I could expand more on in my current draft. So, I plan to get that finalised and posted for people to read and comment/provide feedback on if they so wish. I can't be definite about timescales because I'm fitting this in around family and work commitments as I'm sure everyone is, but maybe sometime next week. Then I'll follow your advice and attempt to distil that down into the something far more succinct that follows the proposal template you have used here and file a new issue.
Sidenote: I honestly wasn't sure whether your tweets were directed at me, provoked in part by me, or unrelated, but I didn't want to just ignore them and take the risk that I'd inadvertently contributed. I'm glad that doesn't appear to have been the case, and I hope that you've been able to take the step back that you mentioned and hope that it has helped.
As you can see, I've just submitted a new proposal: #5777. This proposal references an article documenting my current understanding and point of view:
https://mind-bending-forks.github.io/css-viewport-percentage-length-units/
Feedback is welcome.
I’m in favor of adding the new vhc
unit. In many projects we need both: the viewport height with and without chrome. Currently we’re patching this with JS.
I just realized we have to consider the logical viewport-percentage lengths vi
and vb
as well. We could then end up with three new units; vhc
, vic
and vbc
. Final names to be bikeshed of course.
Maybe @bokand and @AmeliaBR s idea of exposing environment variables would be more manageable than three new units? This would also be more in line with @argyleink s env(scrollbar-inline-size) solution for scrollbars.
height: calc(100vb - env(inset-collapsible-block-size))
This would also open up the possibility to add current-inset
environment values to solve the third use case from @AmeliaBR : "A dynamic layout that always exactly fits the current viewport, regardless of how many browser widgets are surrounding it."
The CSS Working Group just discussed [css-values-4] Add lvh+lvw values
, and agreed to the following:
RESOLVED: Work on the dynamic unit.
Adding another use case: scroll-snapping articles
Scroll-snapping articles like NYTimes The Weekender and this article need both vh and vhc. They would also benefit from a dynamic property as the suggested lvh.
The snapping elements should be able to cover the entire viewport when UA chrome is hidden. Backgrounds can then cover the entire viewport. This can already be done with height: 100vh
.
Content (text++) should never be covered up by UA chrome, and should never be taller than the viewport/icb with UA chrome visible. This would be solved with height: 100vhc
.
Some elements would benefit from having a dynamic value that is updated when UA chrome is shown and hidden. A vertical progress indicator could be updated to fit in the viewport. Text could be translated/shifted to be relative to the bottom of the viewport.
These pages are currently using a scroll-container and not the viewport both because of inconsistencies in propagating scroll-snapping values from root to the viewport, but also because reasoning about viewport sizes is error prone and need JS. WebViews are particularly error prone and hard to debug. It's important that applications that use WebViews can configure and update these values somehow.
@tabatkins and I just committed the changes for this. We named the unit sv*
(small viewport) and also added dv*
(dynamic viewport) per https://github.com/w3c/csswg-drafts/issues/6113
The changes should show up in the ED soon: https://drafts.csswg.org/css-values-4/#viewport-relative-lengths
Official minutes corresponding to the WG discussions leading to these changes are:
We marked some follow-up issues in the draft:
lv*
)?Agenda+ to confirm the unit names and request republication.
I'm a fan of the new units, I think they make sense as spec'ed. I think the complaints I'm seeing about proliferation of CSS units are understandable, but they overlook the fact that today 100vh isn't useable on mobile without a bunch of additional work.
However, I don't think this problem can be solved in a satisfactory way without also dealing with the visible viewport when the on-screen keyboard appears. Today iOS browsers display the on-screen keyboard over the bottom of the viewport, and Android/Chrome shrinks the viewport to appear above the keyboard.
To provide a concrete example, if you were to define this CSS class using the proposed units:
.bottomQuarter {
position: fixed;
top: 75dvh;
height: 25dvh;
width: 100vw;
}
It would be hidden by the on-screen keyboard on iOS, and would appear above the keyboard on Android/Chrome. The same problem occurs if you define it using:
.bottomQuarter {
position: fixed;
bottom: 0;
height: 25dvh;
width: 100vw;
}
Or using units available today:
.bottomQuarterish {
position: fixed;
bottom: 0;
height: 25vh;
width: 100vw;
}
For additional background/sympathy: To workaround the browser chrome retraction and on-screen keyboard issues today I use the window.visualViewport.resize
event (when supported, otherwise window.resize
), and set CSS variables that are equivalent to dvh/dvb
. I also detect viewport resizes, determine if they look like a "keyboard is showing/hiding" resize, then check whether an input or text area is active (to classify it as a keyboard resize); and then I compare a hidden 100vh element to the viewport height to determine if a --keyboard-height
CSS var needs to be set on iOS so that elements that should appear above the keyboard need to be adjusted vertically.
In short, for this to be useful, we also need something like env(keyboard-height)
and env(keyboard-active)
variables.
There is the Virtual Keyboard API: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/VirtualKeyboardAPI/explainer.md
Thank you @fabb - I hadn't seen that. The Virtual Keyboard API proposal looks excellent to me.
My revised points are:
env(keyboard-inset-bottom)
, env(keyboard-inset-top)
and env(keyboard-inset-height)
exclude browser chrome.I think my previous example can be used to illustrate this. Consider an element that occupies the bottom quarter of the visible viewport, and that remains visible above browser chrome, and above the virtual keyboard. And, the Virtual Keyboard proposal and viewport relative lengths are in place. And, we want it to work on browsers that don't support the 2 new proposals. The CSS would look like this:
.bottomQuarter {
position: fixed;
bottom: 0;
bottom: env(keyboard-inset-bottom, 0px);
width: 100vw;
width: 100dvw;
height: 25vh;
height: calc(25dvh - env(keyboard-inset-height, 0px)/4);
}
I think this CSS is fine, but there's a case for adding environment variables for browser chrome offsets too. We will hopefully have environment variables for safe areas, virtual keyboard borders, and foldable device screens; for completeness it seems like collapsing browser chrome offsets should be added.
@tabatkins and I just committed the changes for this. We named the unit
sv*
(small viewport) and also addeddv*
(dynamic viewport) per #6113 The changes should show up in the ED soon: https://drafts.csswg.org/css-values-4/#viewport-relative-lengths
It is so good to se progress on this issue. Thank you!
The floating browser chrome of Safari 15 might introduce some new complexity. There is some ambiguity towards what could be considered the large and the small viewport. There are suddenly not two but three sizes that are of interest:
When browser chrome is floating:
When browser chrome is collapsed in the bottom:
I would expect the large viewport to be the area behind the floating chrome. If I were to use the units to size images to fill the entire screen, this is the area I want to fill, even though there is browser chrome floating above.
The small viewport though, would that be the area above the floating chrome (the smallest area), or the area when the browser chrome is collapsed at the bottom of the screen?
@johannesodland it seems the webkit team is currently toggling the value of safe-area-inset-bottom
based on the browser chrome being collapsed or not.
@johannesodland it seems the webkit team is currently toggling the value of
safe-area-inset-bottom
based on the browser chrome being collapsed or not.
They seem to toggle both vh
and safe-area-inset-bottom
. These are the values I get on the iPhone 11 Pro simulator:
When browser chrome is floating 100vh = 768px env(safe-area-inset-bottom) = 112px
When browser chrome is collapsed at bottom 100vh = 716px env(safe-area-inset-bottom) = 0
There are essentially three sizes here: 768px – height behind the expanded/floating interface 712px – height when interface is retracted 656px – height above the expanded/floating interface
I can se a few issues here:
Fixed and stable
The spec declares that the large and the small viewports are fixed and stable. This is what mobile browsers have converged on for vh
, but Safari 15 seems to reintroduce a dynamic vh
that toggles when UA interfaces are expanded or retracted. This might cause issues with reflow, which was the reason browsers moved to a fixed vh
unit in the first place: https://developers.google.com/web/updates/2016/12/url-bar-resizing
Defining the large viewport The spec defines the large viewport as such: "... the large viewport size: the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be retracted. "
The issue here is that with Safari 15 you now get the largest viewport when the UA interfaces are expanded and floating above the viewport, not when it is retracted. It's the opposite of most current mobile browsers.
Defining the small viewport One of the motivations for the small viewport is apparent in the example: "An element that is sized as height: 100svh, for example, will fill the screen perfectly, without any of its content being obscured, when all the dynamic UI elements of the UA are shown."
The smallest area where nothing is obscured is the area above the floating interface. If svh
maps to this area you would be sure no content is obscured. But then you would have no way to reference the area with the UA interfaces retracted.
It could be more sensible to map svh
to the height when the UA interfaces are retracted. This is the size that is most common when users are interacting with the page, and it also maps to document.documentElement.clientHeigh
and height: 100%
inside the root element. This would make content fit perfectly into the viewport when it is at it's smallest, but would not solve the "no content obscured" use case.
I think the spec might have to deal with floating UA interfaces. A also believe that is needs to address that the viewport can be at its largest when UA interfaces are visible, and the smallest when UA interfaces are retracted. This is the complete opposite of how it is in most browsers now.
Safari 15 seems to reintroduce a dynamic vh that toggles when UA interfaces are expanded or retracted
Since iOS Safari seems to have changed in a way that won't comply with these new spec changes and I just remembered that smart banners possibly affect viewport units, we might need some webkit eyes on this? @smfr?
@jensimmons could potentially also provide some insight as well?
I wanted to see for myself and verify what @johannesodland posted above, and here are my thoughts/observations (that are mostly just a rehash of what Johannes said above):
Using this page as a playground https://codepen.io/afrehner/full/MWmyZEq and having downloaded the XCode 13 beta in order to get access to the mobile version of iOS 15's Safari, I was able to take this video:
https://user-images.githubusercontent.com/3054066/124822498-2f98d680-df2d-11eb-9efa-853fb0cff19d.mov
Observations:
vh == lvh == (vh as currently defined)
vh == svh
vh == svh
vh == lvh
Essentially, Safari is now treating vh == dvh
, and with that, all the good AND bad that comes with it. For example, notice the amount of layout shift when looking at section four
; because all the content above it is using (d)vh
, when the value of vh
changes, four
dramatically shifts where it is. This will only get worse the more content above you that uses the (d)vh
value. We're now (kind of) back to where we were in the beginning, with vh
being dynamic!
I think, more than anything, this emphasizes the importance of getting the s
/d
/l
*vh
units standardized soon, so that browsers vendors can experiment with their interfaces while allowing developers to build websites that won't be changing on them over time.
The CSS Working Group just discussed Values and Units L4
, and agreed to the following:
RESOLVED: "dynamic" viewport does indeed use units, not env()
RESOLVED: Add lvh as explicit "large viewport" unit
RESOLVED: vh/etc are deliberately UA-defined
Thank you to everyone expressing interest in and concern about what Safari for iOS15 is going to do. Yes, in the first few betas Safari was experimenting with changing vh
to work like the new dvh
unit. We are still working out the details of how the new Safari will work. Future betas will test other choices until we figure out what's best. It's too early to assume what you see in beta is what will ship in the fall.
@jensimmons Glad to see it's on the radar at the Safari team. I do hope that you will stay in touch and collaborate with the people behind other browsers to come to very consistent, standardised implementation in all browsers. This whole issue was created because some browsers showed unexpected behavior when using 100vh compared to others.
It would be a such a shame if all these years of struggle, discussions, finding hacks to make things work cross-browser and now finally introducing additional units to really fix the issue, if afterwards behavior still isn't the same across the board. That would be such a waste of time and effort. This should not really be about Apple's individual opinion but please make this a united decision. Only then these units have a real purpose, otherwise I'm afraid we might as well throw all of this in the bin, while we are so close to a solution. :)
When the issue/PR about the changes to vh
is created, could you please link to it here? I would like to share some thoughts on it but want to wait until there's a focused discussion on it.
Thanks, and it's great to see this resolved!
Alright, officially published the 4-way v/sv/lv/dv spec at https://www.w3.org/TR/css-values-4/#viewport-relative-lengths
Opened two issues for follow-up discussion: https://github.com/w3c/csswg-drafts/issues/6454 about enforcing v* as a static unit, and https://github.com/w3c/csswg-drafts/issues/6453 about the relationship with the actual initial containing block. We also have https://github.com/w3c/csswg-drafts/issues/6026 open about scrollbars.
Latest info
Added
lvh
,svh
,dvh
,lvw
,svw
, anddvw
units.See https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-863677668 and https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-880040513 for more details. 🎉
Original content below:
Background
vh
is defined asEqual to 1% of the height of the initial containing block.
Perhaps the current behaviour 1 2 could also be defined asIn other words, on devices where the browser chrome changes size (e.g. mobile devices),
100vh
is actually larger than the viewport when the browser chrome is maximized, and thus overflows.A brief history of the
vh
unit is outlined here https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-542420036Proposal
vhc
(c = "with chrome", but it could be something else) could be defined asOn devices without a changing chrome size (e.g. desktop devices),
1vh === 1vhc
.Advantages and Drawbacks
Pros and Cons list for each proposal
Original content of this section:
A drawback of
vh
units is that content will be cut off when (1) you load a page and (2) when you scroll upwards, while the content fits when you scroll down and the chrome is minimized.The
vhc
unit would be the inverse: content would fit the page when (1) you load the page and (2) when you scroll upwards, but you would see additional content (or whitespace, depending on the implementation) when the chrome is minimized.It also would provide a better experience than
vh
for games and other full-screen content that doesn't or shouldn't scroll at all.In the end, this proposal does not completely solve the issue of
1vh
needing to be different values at different times. However, it does at least give the developer a choice in which value that they want to use.(For what it's worth, my personal preference is that I would end up using
vhc
units for responsive designs, because I would rather have additional content visible or some whitespace added, rather than have content cut off and not visible.)Alternative Proposals
And a breakdown of the pros and cons of each proposal so far
Current Workarounds
As it stands, web developers that want to have a full-height website are either reliant on javascript 1 2 3 to get
vh
units to not cut off content, or just tend to avoid 1 usingvh
units altogether.Unrelated
This is my first time proposing, so if I did something wrong or need to improve something please let me know! Thank you for your patience. :)