[CSSWG] Virtual F2F 2021-04-06 Part II: CSS Values [css-values]

=========================================
  These are the official CSSWG minutes.
  Unless you're correcting the minutes,
 Please respond by starting a new thread
   with an appropriate subject line.
=========================================


CSS Values
----------

  - RESOLVED: Work on the dynamic unit (Issues #4329 (Add vhc value)
              and #6113 (Add lvh+lvw values))
  - Some spec text will be created for this new unit in order to
      further debate and discussion. There will need to be further
      thought on interactions with things like Animations.
  - A separate issue will be opened to consider if dynamic value could
      be in env() instead in order to make it easier to read and to
      make it not seem like a default value that authors are
      frequently using.

===== FULL MEETING MINUTES ======

Agenda: https://github.com/w3c/csswg-drafts/projects/16

Scribe: TabAtkins

CSS Values 4
============

Add vhc value & Add lvh+lvw values
----------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/4329
  github: https://github.com/w3c/csswg-drafts/issues/6113

  fantasai: 6113 is a specific part of 4329
  fantasai: 4329 is a long discussion about how people are really,
            *really*, REALLY unhappy how on mobile the viewport units
            don't represent the size of the viewport
  fantasai: And the reason is that there are parts of the browser
            chrome that appear and disappear dynamically as you scroll
  <astearns> +1 to unhappiness
  fantasai: so a bunch of UAs decided that the viewport units are the
            size of the viewport with all the dynamic chrome hidden,
            so a 100vh element will be partially obscured if anything
            *is* showing
  fantasai: Which is fine for some content, and really problematic for
            others (like toolbars or headers that have to be visible
            at the top/bottom of the screen)
  fantasai: So we've had a discussion about what values authors need
            to get the useful behavior.

  fantasai: Three things are needed.
  fantasai: One is size of the viewport with chrome present, so they
            can size into that minimal space and never get things
            overlapped.
  fantasai: Another is the size without the chrome, so they can size
            to the maximal space and get all the space filled when
            it's all hidden.
  fantasai: And finally, the dynamically-changing current size with
            whatever chrome is currently showing, so it'll perfectly
            fit the viewport in all cases.
  fantasai: Currently we are only providing #2, and that's a problem.
  iank: I thought vhc did change?
  fantasai: No it's static, and also it's not defined yet because we
            haven't decided on a name.

  fantasai: So the issue I tagged here is someone saying "how about we
            introduce lvh/lvw/etc" and that would represent the
            dynamic size of the viewport.
  fantasai: And then vhc would be the with-chrome static size, and
            existing vh would be without-chrome static size.
  <cbiesinger> what does lv stand for?
  <astearns> cbiesinger: Layout Viewport height
  <cbiesinger> ah
  fantasai: In A Coruña we discussed this, and a suggestion was
            because of the way viewport units compute, and to
            emphasize the dynamic-ness, possibly exposing the dynamic
            version as an env() value instead of a unit.
  fantasai: And that might be less scary to implement.
  fantasai: Viewport units have to be computed whenever the window
            changes; making it happen on scroll would be worse.

  smfr: Drill down on "dynamic change"
  smfr: in iOS, when the chrome animates in, I don't think we'd
        animate the unit; we'd snap it.
  smfr: We have a notion of the UI being in an unstable state.
  smfr: Like, position:fixed is magic that happens in the compositor.
  smfr: Web content doesn't see the dynamic change, it sees things
        flip, and the dynamic stuff happens behind the scenes.
  fantasai: I think that's fine, as long as the layout is correct when
            UI is stable.
  fantasai: If the in-between state is optimized in ways that's
            probably fine.
  fantasai: Someday animating it might be nice and performant, but for
            now it's fine. From the author's POV, it's the end states
            that matter.
  TabAtkins: I agree, it seems like the end states are the most
             important here

  emilio: Same about end states, and that Firefox Mobile uses similar
          concepts. Webview only knows about the final states, not
          intermediate.
  emilio: Also this sounds like fullscreen, a bit. We have
          display-mode MQ which tells you some stuff about the browser
          screen.
  emilio: Would having these units and an MQ to switch between them
          work?
  TabAtkins: Don't understand what you mean.
  emilio: Instead of having a dynamic unit, just using the vh or vhc
          based on an MQ.
  fantasai: I do want to keep it open for the future to be animated.
  TabAtkins: I think this supports that, if we don't do dynamic *at
             all* right now.
  fantasai: The computed-ness is still problematic
  emilio: Computed value will *definitely* change with env(), they get
          substituted at var() time
  fantasai: Or we have a unit that is used-value time. I don't think
            people need computed behavior here.

  emilio: We have this already with percentages on a fixpos
  iank: Yeah, or percent height on <html>, they dynamically change
        based on chrome showing. So this concept is already exposed.
  iank: So given the existence of height:100% on these elements, I
        don't know if we should try to avoid exposing this by using
        the MQ path.
  smfr: height:100% doesn't change on iOS
  emilio: It does for fixpos on Gecko, but unsure about on <html>
  emilio: This is historically not the most interoperable bit of
          mobile engines...
  <iank> here is a testpage https://bokand.github.io/demo/urlbarsize.html

  emilio: Could we spend some effort figuring out what we want the
          existing primitives to do?
  fantasai: Yes, but I think we also need to add the new ones.
  fantasai: Either way we'll need these three kinds of values.
  fantasai: Deciding which one the height:100% maps to is probably a
            little more acceptable once we have the ability to change
            to another one, via new units.
  fantasai: But right now people are just very unhappy

  chrishtr: If you set vh units it's the full size, ignoring chrome.
  chrishtr: If you use vhc it subtracts chrome, so if you scroll up
            you see a gap
  chrishtr: lvh theoretically animates, but at least shows the right
            value on stable. If you don't animate it'll show a gap
            during unstable, and then snap.
  fantasai: One thing you can do is make the animation always snap to
            the larger size during the transition.
  fantasai: It doesn't have to lag at the size you started at, could
            be either; using the larger size always sounds better.
  chrishtr: So when you start the animation, snap to the larger thing,
            do a main-thread relayout and possible introduce jank to
            the browser's interaction model.
  chrishtr: Layout could take time, there could be a rAF callback...
  fantasai: Right, but I think making it pretty is secondary to making
            it usable at all.
  chrishtr: I find the whole area pretty confusing for ideal UX.

  fantasai: Example: I've got a coding tutorial page, with pretty
            pictures.
  fantasai: Long scrolling page.
  fantasai: The elements I want to be viewport height are pictures and
            code blocks, both scrollable.
  fantasai: It's *really awkward* to have a scrollable block taller
            than the viewport; you can't reach the scrollbars easily.
  fantasai: So for usability reasons I want the code block to be at
            most the height of the viewport.
  fantasai: But I want the viewport size *with chrome factored in*--
            the smaller size--so that scrollbars will always be
            accessible, but the size of the blocks aren't constantly
            changing and causing the page to shift.
  fantasai: I don't want larger (overlaps) and I don't want dynamic; I
            just want to make sure the entire box is visible when it's
            on screen regardless, so I can access both scrollbars.
  fantasai: But for the pictures, I want them to fill the viewport,
            because it looks better to always fill the viewport, and
            it's okay to have them be cropped a bit.
  fantasai: So I want them to fill the whole viewport when the chrome
            is hiding. And it's okay if the chrome comes in and
            obscures a little of the top or bottom of the image.
  fantasai: And similarly I don't want this to be dynamic, because
            it'll cause the page to shift around, I want stable.
  fantasai: And then *thirdly* I could have a sidebar that wants to
            fill the height of the page, and it needs to be dynamic -
            using all the height that's available when chrome is
            hidden, but not cropping anything when chrome is showing.
  fantasai: So we want all three behaviors; we want to make sure that
            dynamic behavior is *clearly dynamic* and won't get reached
            for accidentally.
  chrishtr: So the sidebar example wants the dynamic example, right?
  fantasai: Yeah.
  TabAtkins: Have problems with the toolbars currently, even with
             position:fixed. [gives example]
  iank: People do dialogs, for example, that want it to fill the
        viewport, but too deep in the DOM to use 100%.
  iank: There's a lot of examples.
  chrishtr: So a fullscreen, or fullscreen minus margin, dialog, you
            probably want it to dynamically resize when you hide the
            omnibox?
  iank: Yes.

  <plinss> https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/VirtualKeyboardAPI/explainer.md
  plinss: Microsoft is doing some virtual keyboard API (link), wanna
          make sure we coordinate with this work
  iank: I think this is a slightly different usecase here
  iank: I don't think you want lvh to change on keyboard showing
  fantasai: I agree with Ian, and think we discussed this in A Coruña
            as well and came to the same conclusion.
  fantasai: Wanting keyboard to change your layout is something much
            less common you should opt yourself into.
  iank: Especially like adding an extra keyboard above the UI keyboard
  astearns: If that's the case, I'd want to see noted the reasons why
            we're explicitly not doing that.
  fantasai: Sure, we can add a note for that.
  smfr: I think there's a diff on Android vs iOS for whether keyboard
        is an overlay vs viewport shrink
  smfr: There's also the visual viewport API that tells you when it
        changes due to the keyboard
  dlibby: There's three modes - keyboard resizes the layout viewport
          (Android), keyboard resizes the visual viewport (Windows/
          iOS), and virtual keyboard is third (nothing page-observable
          happens besides some events firing)

  dbaron: One thing to be careful about with dynamic unit is that
          there's an assumption that users will make some scroll
          gesture, and the toolbar will appear or disappear, and the
          unit will resize things, and somehow there's magic that'll
          happen that puts things in the positions they're expected to
          be in.
  dbaron: I think we should be careful not to assume that magic will
          just work, because it's actually quite hard. When things
          resize, things move.
  chrishtr: You mean hard for the dev to make sure things move in
            predictable ways?
  dbaron: Possibly both. I think there will be unexpected results
          where they use the dynamic unit, get the right size, but not
          the right position.
  florian: Right, and I don't think in general you can't guarantee
           anyway because too much of the layout has changed.
  chrishtr: What do you mean by position of content?
  florian: If your page is just a linear stream of content, and you're
           just using the unit for height, you can expect the position
           of the resized bit to not change.
  florian: But if you use the unit in width, and this changes how many
           columns fit, etc, there might be arbitrary layout changes
           on the page that make it undefined what it means to be
           "same position"
  TabAtkins: 2 items, both 100lvh
  TabAtkins: both change, and bottom one ...
  TabAtkins: causes unexpected position changes
  smfr: Scroll anchoring can probably help there
  TabAtkins: Agree

  smfr: If this is a unit that changes value, we need an event to
        inform you of the change. Possibly this is the resize event;
        if so, we need to sync this unit changing with the resize
        event firing
  fantasai: Does resize change due to this?
  smfr: We do fire the resize event....
  smfr: It fires on inner height, which does match this I think
  <dlibby> visualViewport resize does fire already, I believe
  smfr: There's several things that need to be accounted for.
  iank: I posted a testcase a bit ago, that should show in a
        particular browser when things change based on user gesture
  iank: I think resize event should fire when innerHeight changes
  florian: Could this get us into loops, if the content using the
           viewport units gets smaller than the viewport height?

  fantasai: We can get into the details for that after we decide
            whether to do this or not at all ^_^
  fantasai: So we need to decide whether to add these functionalities
            or not
  fantasai: If so, add them as units, as env(), as something else?
  astearns: Are we lacking a second stable resolution?
  fantasai: We have a resolution, just not a name.
  fantasai: We don't have a resolution for the dynamic version.
  fantasai: We should have consistency between them.
  fantasai: The proposal for dynamic uses a prefix; we might want the
            small static one use a prefix as well, so Xvh rather than
            vhX

  chrishtr: Coming back to use-case for dynamic, a 100% height sidebar
  chrishtr: Why can't that be position:fixed top/bottom:0?
  iank: It can, but often people will embed sidebars deep in other
        elements
  iank: It'll break their site layout if it's fixpos
  iank: There can be a fixpos containing block between it and the root
  iank: People will often develop for desktop-first sidebars, and
        handle mobile after, and their page structure is already set.
  florian: Another is you might not necessarily want to be on top of
           things. Think app, not document, with toolbars around a
           content area - a grid with toolbars in side cells and an
           overflowable center area
  florian: Entire UI is supposed to fit the screen at all times. If
           browser chrome pops in and out, the page's UI shifts, but
           it should all always be visible.
  chrishtr: So this is a site that doesn't scroll?
  florian: Yes, the overall site doesn't scroll, just the regions.
  jensimmons: Right, fixpos would work *only* if people were already
              using abspos for their layout, not if they were using
              Grid/etc.
  jensimmons: Could we do a thing where we have units to measure the
              constant states, and then use env() for the dynamic
              things?
  TabAtkins: That was fantasai's suggestion, to make it really obvious
             that this is dynamic and different from the others, make
             sure you really want it

  chrishtr: Could one of y'all share an example that would help
            explain it?
  florian: [shows off a music editing app on his phone, with a toolbar
           on bottom with sheet music taking up the content area]
  florian: I always want the toolbar to be showing regardless of
           chrome showing or not, and I don't want the toolbar to
           overlap the end of the sheet music if I scroll to the
           bottom.
  florian: So probably the whole thing is a Grid, with a height of
           env(viewport-height) or something, and the toolbar's grid
           cell is fixed height, etc
  fremy: Wouldn't stickypos do this, too?
  sanketj: yeah, seems like stickypos too
  florian: My claim isn't that you couldn't do it with stickypos or
           whatever, but rather if you're thinking about your entire
           layout in Grid, which you might very well do because it's
           modern and convenient, you can express this all in Grid,
           but then if it fails on mobile because the viewport units
           don't work...
  iank: Important to think about is that web devs might start by
        developing with a grid, which is deep in the DOM; to size it
        to the viewport they need to size all the elements in the
        ancestor chain carefully. Using vh is a very simple and easy
        tool there. It's a big change in thinking to instead switch to
        fixpos or stickypos.
  iank: So If they started with this as a grid, and were sizing to
        `calc(100vh - 10px)` or whatever, it would be a big change.
  TabAtkins: ...
  TabAtkins: Want to make sure that we don't create cliffs
  florian: And if you have stickypos, the toolbar needs to be a child
           of the scroller; in Grid it's a sibling of the scroller
  jensimmons: The use-cases we've seen, attaching to the bottom, is
              *one* of *many* use-cases for viewport units; I've
              demo'd viewport unit a bunch on stage and have never
              even used this case.
  jensimmons: And 100vh isn't the whole thing - 50vh items stacking is
              reasonable.
  chrishtr: Returning to florian's app example, the root scroller
            doesn't have overflow, right?
  florian: In a simplified version, yes, it's a flexbox that fills the
           viewport. The content area that contains the sheet music
           has overflow:auto.
  chrishtr: So the interaction model they want is you can scroll the
            music, nothing else; you can always tap the play button.
  florian: Yeah.
  chrishtr: So in this case, when it first loads on chrome mobile, the
            url bar will show and then never disappear, since it only
            disappears if you scroll the root scroller.
  cbiesinger: I think apps sometimes do a scrollTo(1px) to cause the
              URL bar to autohide
  florian: That might explain why the Firefox behavior is so confusing/
           uncertain
  chrishtr: Yeah there's bugs around that.
  chrishtr: So the site could use vhc perhaps, but if they use the
            dynamic version they'll never see it adjust.
  chrishtr: So I was concerned about this responding to user gestures
            hiding the bar - that needs to be smooth.
  chrishtr: But if it just needs to be resized to the correct new
            area, I can see the use for this dynamic unit
  <fremy> totally agree with cbiesinger here. if you use a fixed grid
          over the screen, there is no way to auto-hide the chrome as
          a user, and the problem just doesn't exist in that case

  florian: So there's definitely a bunch of issues, but does it seem
           reasonable to take a resolution to pursue the dynamic
           thing, and possible scale it back afterwards?
  astearns: And are we shooting for a unit or env() ?
  iank: I'd err towards units, since that's what webdevs are already
        used to.
  iank: I don't find the argument about dynamic changes compelling -
        the other units already dynamically change on window resize.
  astearns: I think it's much more common for webdevs to resize the
            tab to check it responds properly, less experience with
            showing/hiding chrome on a mobile device.
  fantasai: The nice thing about env() is that it's more obnoxious to
            use, so it's more of an explicit decision.
  fantasai: On desktop it doesn't have this dynamic problem, only on
            mobile.
  fantasai: So I feel like we'll get less people doing it by default.
  <florian> +1 to fantasai's obnoxious-on-purpose syntax argument

  astearns: People who teach CSS, do y'all have an opinion?
  jensimmons: I could go both ways.
  jensimmons: vh means the most pixels, vTBA means the least pixels,
              and both are fixed.
  jensimmons: A third unit meaning a dynamic changeable value, that
              could be confusing to people.
  jensimmons: But iank's point is compelling, where authors are
              already used to these as units.
  jensimmons: But fantasai's point about this being an env() so people
              have to go look for it might make sense.
  rachelandrew: My gut is a unit, same as the others, but I get how we
                don't want it to be the default people use, and making
                it look different can help there.
  rachelandrew: So as a teacher, units are easier to teach, but I get
                the reasoning behind the other.
  leaverou: I think it makes more sense as a unit, due to symmetry.
  leaverou: Might be easier to read as an env() because it can have a
            longer name; unit names are cryptic.
  leaverou: But env() names can get pretty long, especially in
            calculations.
  iank: There's already polyfills for this; they act like a unit
        setting a css variable.
  <TabAtkins> That sounds like it's similar to env(), then?
  <jensimmons> I always find answering questions like this (unit vs
               environmental var) are easier to understand when I code
               some demos. Actually write out the code.

  astearns: I propose that we resolve to work on this dynamic unit.
            Get spec text together, with examples, and open separate
            issues for moving it to env(), what to do with animations,
            etc.
  chrishtr: I think that sounds great, one more thing, I hope we can
            go forward with vhc as well.
  astearns: We do have a resolution for that, we just haven't gotten
            it into the spec
  fantasai: And haven't decided on the name. And it might make sense
            to make sure these are consistent.
  fantasai: Might all work best with a prefix.
  fantasai: I propose to use "s" as a prefix for the small, static
            size, and "d" as a prefix for dynamic one.

  RESOLVED: Work on the dynamic unit.

  <iank> https://www.npmjs.com/package/postcss-viewport-height-correction
         is one example of substitution via postcss

  chrishtr: Not only do we hear a lot that this is a problem, Chrome
            is definitely interested in exploring this and working
            with devs.
  chrishtr: If anyone has partners who can work with us, or has more
            examples, please contact me.
  <fantasai> chrishtr:
https://github.com/w3c/csswg-drafts/issues/4329#issuecomment-730549876
             might be worth a read

Received on Monday, 24 May 2021 22:47:34 UTC