Visitar URL original
[css-values-4] Add lvh+lvw values · Issue #6113 · w3c/csswg-drafts · GitHub
Skip to content

[css-values-4] Add lvh+lvw values #6113

Closed

Description

@brunoais

Note: Contents based on the vhc proposal

Background

vh is defined as Equal to 1% of the height of the initial containing block. Perhaps the current behavior 1 2 could also be defined as

Equal to 1% of the height of the initial containing block with browser overlays hidden or collapsed.

In other words, on devices with a browser's chrome or any other variable sized overlay (e.g. mobile devices), 100vh is actually larger than the viewport when the browser chrome is maximized, and thus overflows, leading to scroll bars to appear.

A brief history of the vh unit is outlined here #4329 (comment)

Additionally, browsers may come in the future where the chrome or any other collapsible browser overlay may be placed on the sides. For example, a browser that, in landscape, shows the chrome on the short side or a browser that shows a helper overlay on the side while the navigation is on the top overlay. lvw is meant to handle when such possible cases comes to light. If anything, lvw will bring consistency when using lvh to have a lvw counterpart.

Proposal

lvh (as "Layout Viewport height", but it could be something else) defined as:

Equal to 1% of the height of the layout viewport of the user agent

In other words: 1% of the height of the user-visible part of the web page when no zoom applied.

And it's width counterpart:
lvw (as "Layout Viewport width", but it could be something else) defined as:

Equal to 1% of the width of the layout viewport of the user agent

In other words: 1% of the width of the user-visible part of the web page when no zoom applied.

How to keep lvh/lvw in sync?

Solving scroll bars add and remove infinite cycle

If an infinite cycle exist in the calculation such that:

  1. Before finishing the calculation for the page, and scroll bars are auto and they would be needed.
  2. Due to dynamic units, after the calculations, no scroll bars necessary anymore.
  3. After readjusting to not requiring scroll bars, a resize forces back the need for scroll bars again.

This is how MUST be solved:

  1. Add scroll bars vertically.
  2. Problem solved?
    1. If yes, keep the scroll bar
    2. layout the rest.
  3. Add a horizontal scroll bar
  4. Problem solved?
    1. If yes, keep the scroll bars
    2. layout the rest.

If 1 or 3 is used and the UA has a console, the browser, by default, SHOULD create a CSS warning explaining the problem which includes the tags that lead for the need to add the scroll bars.
However, the browser MAY provide means to turn it off and also MAY only warn once per conflict per page load.
The way such message expresses the need is up to the UA itself. The UA MAY add more information as it sees fit.

UA responsibilities for the variable characteristics of the unit.

The UA is responsible for choosing how often to update the calculated value of the unit and the refresh rate for the visual viewport.
The UA SHOULD keep into account the hardware capabilities and power settings of the host machine.
The UA MAY provide options for the user to select how smooth he wants the experience to be through user options. It is up for the UA to decide what options the users have access to and how they are presented.
The UA MAY cache how the elements look with and without such overlays, relevant in-betweens, etc...

For example: on an Android device which has power settings, the UA can decide to slow down the refresh rate to save battery.

Advantages and Drawbacks

Pros and Cons list for proposals to vhc which similarly apply to lvh

vhc isn't enough to solve the problems at hand because it doesn't specify a percentage size for the whole currently visible page. If using vhc and vh together:

  • When the chrome is open
    • if using vhc → Size is right
    • if using vh → Content overflows and scroll bars may appear because of it.
  • When the chrome is closed
    • if using vhc → A gap in content will appear or elements meant to be placed at edges will be placed elsewhere
    • if using vh → Size is right

Intermediate verdict: Seems like js will be needed to swap between those two.
However: browser chrome in Chrome and Firefox (as 2 examples) don't only have open and close. They progressively go between those two.

In order to support those intermediate states, without lvh, positioning will have to be done using javascript leaving vhc and vh scarcely used.

lvh solves by allowing to place the content based on the whole visible part of the web page without the need for js work arounds.

Additionally, the same way as the usage of variables is not an alternative to vhc, it is also not a viable alternative to lvh

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 using vh units altogether.

Alternatives

The vh-sizing, in my opinion, is the only alternative I know to be a viable towards lvh

Assurances/Examples

@100% ZOOM 100lvh => full screen

With zoom at 1 (100%) (I.e. no pinch zooming applied or pinch zooming not available)
An element with the following CSS computed:

margin: 0;
padding: 0;
border: 0;
height: 100lvh;
width: 100lvw;
position: fixed;
top: 0;
left: 0;

Ensures that:

  1. Element covers the whole visual viewport without any pixels in excess or at fault.
  2. Must not be the cause for scroll bars to appear.
  3. If scroll bars already exist, the lvh will take the scroll bars size into account

However, the user may zoom in and then scroll (or pan) to see the whole intended content with a larger visual size in his device screen.

With vhc, when the chrome is closed, a gap would appear somewhere on the top or the bottom of the page or centered elements wouldn't actually be centered, etc... It still would require javascript to solve a CSS problem.

fixed at 100lvh top then translate up => always at the bottom of the screen

With zoom at 1 (100%) (I.e. no pinch zooming applied or pinch zooming not available)
An element with the following CSS computed:

margin: 0;
padding: 0;
border: 0;
max-height: 100lvh;
max-width: 100lvw;
position: fixed;
top: 100lvh;
transform:translatey(-100%);

Ensures that:

  1. Element will always be at the bottom of the viewport and fully visible.
  2. Its position must not be the cause for scroll bars to appear.
  3. If scroll bars already exist, the lvh will take the scroll bars size into account.

For this specific case, I do recommend:

top: auto;
bottom: 0;
transform:initial;

Instead of the above but I believe it is a viable way of exemplifying.

@100% zoom + fixed chrome size or viewport set to width=device-width

On devices without a changing chrome size (e.g. Most desktop devices), scroll bars hidden and with viewport set as width=device-width these two are always true:

  1. 1vh === 1lvh
  2. 1vw === 1lvw

100lv[hw] the html tag and its size looks like viewport set as width=device-width

If you specify <html> in CSS as:

html {
  margin: 0;
  padding: 0;
  border: 0;
  height: 100lvh;
  width: 100lvw;
}

The HTML tag will behave the same as <html> currently does by default when the viewport is specified as:
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1"> and no scroll bars are necessary

@100% ZOOM 100lvh and 1px margin-bottom => full screen + scroll bars + 1 px gap

With zoom at 1 (100%) (I.e. no pinch zooming applied or pinch zooming not available)
An element with the following CSS computed:

margin: 0;
margin-bottom: 1px;
padding: 0;
border: 0;
height: 100lvh;
width: 100lvw;
position: fixed;
top: 0;
left: 0;

Ensures that:

  1. Element covers the whole visual viewport without any pixels in excess or at fault.
  2. Must be the cause for automatic vertical scroll bars to appear
  3. If this is the only item that cause automatic scroll bars to appear, the scroll bars that appear due to this margin, can only scroll by 1px.
  4. If on the root: overflow-y is either hidden or clip, From the user's perspective, there's no visual difference wether margin-bottom is 0 (previous example) or 1px.

However, the user may zoom in and then scroll (or pan) to see the whole intended content with a larger visual size in his device screen.

Unrelated

This is my first time proposing, so feel free to help me improve this proposal!
Thank you for your patience.

Activity

  1. johannesodland commented on Mar 20, 2021

    @johannesodland
    Contributor

    @brunoais Have you considered pinch zooming, when the visual viewport is smaller than the layout viewport and the ICB?

    In the example above the element with dimensions 100vvw and 100vvh will shrink towards the top left corner of the layout viewport. If the user is zooming into a different part of the layout viewport the element will become partially visible or disappear outside the visual viewport altogether.

  2. brunoais commented on Mar 21, 2021

    @brunoais
    Author

    If my understanding of what layout viewport (= visual viewport 100% zoom) and initial containing block is correct, pinch zooming does nothing user visible to vvw and vvh affected elements. That means they cannot be affected by zoomed in or zooming out.
    I don't understand or grasp the spec details of how you believe the element would shrink towards the top left corner.

    About browser zooming, specially how it's done in mobile browsers, everything seemed fine until I gave a quick prototype (js-made) to my grandpa and could notice that the expectation of the user really is a zoom on everything in the page and just text increasing or incorporated elements increasing (with text size change) but not their container simulated sized with vvh.

    I may end up changing the name to lvh lvw. We'll see...

    What I will write will hopefully not make any difference for websites with: <meta name="viewport" content="width=device-width">
    However, I do want to cater for websites that allow pinch zooming so that the results are the way the user would expect, so I'll update above.
    Thanks for the heads up

  3. brunoais commented on Mar 21, 2021

    @brunoais
    Author

    @johannesodland I updated the proposal. Please check if it makes more sense now.

  4. johannesodland commented on Mar 21, 2021

    @johannesodland
    Contributor

    I may end up changing the name to lvh lvw. We'll see...

    If the units reflect the size of the visual viewport at maximum scale, that is the layout viewport (in my understanding). Naming it lvh and lvw would be a better idea.

    I’m not opposed to the suggestion. Having units that reflect the current size of the layout and visual viewport both have their merit.

    I’m worried about adding more confusion around viewports. If they’re named after the visual viewport they should reflect the size of that viewport (window.visualViewport.height In JS) and not the layout viewport. lvh and lvw seems like better names for what you want to achieve.

    Be aware that units that are synchronized with the viewport will change every frame, and can cause major performance and usability issues if used without care.

  5. johannesodland commented on Mar 21, 2021

    @johannesodland
    Contributor

    @johannesodland I updated the proposal. Please check if it makes more sense now.

    I think the naming makes more sense now. Maybe update the title as well?

  6. changed the title [-] [css-values-4] Add vvh+vvw values[/-] [+] [css-values-4] Add lvh+lvw values[/+] on Mar 21, 2021
  7. brunoais commented on Mar 21, 2021

    @brunoais
    Author

    I may end up changing the name to lvh lvw. We'll see...

    If the units reflect the size of the visual viewport at maximum scale, that is the layout viewport (in my understanding). Naming it lvh and lvw would be a better idea.

    Yep. I ended up aiming to the layout viewport instead of the visual viewport due to what I believe is the user's expectation.

    I’m not opposed to the suggestion. Having units that reflect the current size of the layout and visual viewport both have their merit.

    I agree. What I wonder is if they are worthwhile to implement from the browser's POV. Maybe we can leave a discussion about the vvh to some other time. At this time, people really expect pinch zoom to

    Be aware that units that are synchronized with the viewport will change every frame, and can cause major performance and usability issues if used without care.

    If it's not in effect already, the UA is responsible for selecting a sensible frequency to apply the updates to the layout for the new dimension values. I will explicitly specify that in the proposal.

    @johannesodland I updated the proposal. Please check if it makes more sense now.

    I think the naming makes more sense now. Maybe update the title as well?

    Certainly. Thanks for the heads up.

  8. johannesodland commented on Mar 21, 2021

    @johannesodland
    Contributor

    One more thing. The layout viewport can deviate from the ICB as explained in this comment

    When they deviate the following is no longer true:

    On devices without a changing chrome size (e.g. Most desktop devices), 1vh === 1lvh.
    On devices without a changing chrome size (e.g. Most desktop devices), 1vw === 1lvw.
    
  9. brunoais commented on Mar 21, 2021

    @brunoais
    Author

    I updated my proposal but I'm still thinking whether I misunderstood the ICB and, given so, I did this proposal in a wrong way.
    However, given the comments so far, I hope I'm going the way I want. I hope that is also able to cover most people's needs related to this kind of use-case

  10. added this to the milestone on Apr 2, 2021
  11. astearns commented on Apr 6, 2021

    @astearns
    Member

    In #4329 (comment) we resolved to work on this new dynamic unit

  12. brunoais commented on Apr 12, 2021

    @brunoais
    Author

    lvw can be the solution for: #6026 (comment)

  13. fantasai commented on Jun 18, 2021

    @fantasai
    Collaborator

    @tabatkins and I just committed the changes for this. We named the units dv* (dynamic viewport).
    The changes should show up in the ED soon: https://drafts.csswg.org/css-values-4/#viewport-relative-lengths

    Agenda+ to confirm the name and request republication.

  14. css-meeting-bot commented on Jun 30, 2021

    @css-meeting-bot
    Member

    The CSS Working Group just discussed Add lvh+lvw values.

    The full IRC log of that discussion <Rossen_> topic: Add lvh+lvw values
    <Rossen_> github: https://github.com//issues/6113
    <bkardell_> ScribeNick: bkardell_
    <TabAtkins> https://github.com//issues/4329#issuecomment-863677668
    <TabAtkins> https://drafts.csswg.org/css-values-4/#viewport-relative-lengths
    <bkardell_> TabAtkins: two weeks ago fantasai and I drafted new text for more viewport relative sizes. There was discussion about whether we should do some of these as env variables - we are currently using units
    <bkardell_> TabAtkins: we introduced svw svh for small viewport, for example and a dvh for dynamic viewport ... as discussed in previous discussions dvh only needs to be accurate when it is stable
    <bkardell_> TabAtkins: when the UI is stable, it is the correct size of the viewport
    <bkardell_> TabAtkins: we would love comments or discussion - it's all very bikeshedable right now
    <bkardell_> TabAtkins: if you have strong opinions on units vs env, let us know - we made an editors choice, but we can go either way
    <bkardell_> TabAtkins: it would be great to be able to resolve on these next week (if we have the quorum)
    <TabAtkins> ScribeNick: TabAtkins
  15. astearns commented on Jul 14, 2021

    @astearns
    Member
    RESOLVED: "dynamic" viewport does indeed use units, not env()
    RESOLVED: Add lvh as explicit "large viewport" unit
    RESOLVED: vh/etc are deliberately UA-defined
    

    (from #4329 (comment) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions