Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-position-3] Reinterpret viewport positioned (fixed, sticky) elements wrt virtual keyboard #7475

Open
flackr opened this issue Jul 7, 2022 · 14 comments
Labels
css-position-3 Current Work

Comments

@flackr
Copy link
Contributor

flackr commented Jul 7, 2022

Position fixed is positioned and sized relative to a fixed position containing block which in the absence of no established container is the viewport.

The behavior today when a virtual keyboard is shown varies (see demo for interactive examples). In each screenshot, the left image is what the user would see, and the right is a visualization of the viewports with the blue outline being the size of the ICB / layout viewport / 100vh and the red outline being the visual viewport:

  1. iOS (and ChromeOS) shrink the visual viewport but keep the fixed position viewport the same size. As a result, elements which are fixed position to the top/bottom may be scrolled out of view (even while zoomed out). However, showing the keyboard does not affect layout in any way.

    ios-chromeos

  2. Android resizes the page to the height remaining after the keyboard is shown, changing the fixed position viewport as well as the ICB. This has the consequence of doing a relayout and potentially triggering different media query breakpoints, but also means that position: fixed elements are still fully visible while zoomed out.

    android

We would like to unify the behaviors, and agree that not having a global resize is better, however one of the stumbling blocks when we tried to adopt the iOS model is that developers struggle with being able to create bottom fixed position elements, which has lead to various alternate proposals on top of the iOS model. Let's explore some:

  1. device-fixed is a proposed position to position elements to the fixed viewport regardless of zoom. This fixes the issue when the keyboard is shown as the element is shifted up, however when zooming position: device-fixed content remains the same size which raises concerns for accessibility as well as not preserving the relative size of content on the page.

    device-fixed

  2. Scaled device-fixed is an alternative which preserves the zoom scale but still treats the visual viewport rect as the fixed position rect. This allows you to zoom in on position: device-fixed content but this results in the content intruding more into the viewport. Also, this mode would likely lead to a relayout during pinch zoom as fixed content needs to change size. None of the other approaches require layout during zoom operations.

    scaled-device-fixed

  3. I propose excluding the keyboard from the position fixed viewport. This leads to a very similar behavior to the android one in that position: fixed content avoids the keyboard, except that it would not change the height of the ICB or viewport units. The only content which needs to relayout is that which is sized with respect to the fixed position viewport, and content which is not sized with respect to the viewport can be shifted on the compositor.

    fixed-viewport

    When you zoom in the same thing would happen as currently happens on android, the visual viewport would zoom in but leave the fixed position viewport size unchanged.

    fixed-viewport-zoomed

    Another advantage of this option is that we could easily use the same adjusted fixed viewport as the scrollport for sticky position elements on the root, whereas options 3 and 4 would not implicitly add any support for sticky without adding e.g. device-sticky.

TLDR; In order to close the interop gap while still allowing developers to position fixed position content above the keyboard I propose we adopt option 5.

Each option links to a demo of that option which can be played with on a desktop browser.

@flackr
Copy link
Contributor Author

flackr commented Jul 7, 2022

@bramus @bokand FYI

@bramus
Copy link
Contributor

bramus commented Jul 13, 2022

I’ve given all proposals in here a lot of thought and while I do like the general idea behind Option 5 (PosFixedViewport). But, I have a few concerns to be fully convinced of it:

  1. This would alter the existing behavior of position: fixed on all iOS browsers + Chrome on CrOS. This demo here – which mimics a bottom navigation bar – for example would no longer work as the author expected it to work. This will annoy authors.
  2. Authors cannot easily feature detect wether the new or old behavior is being used. Therefore they cannot predict how the site will look with the OSK shown. This will annoy authors as well.
  3. This does not provide a solution for authors to stick something against the Visual Viewport, something that might come in handy for Floating Action Buttons or Toolbars which do need to stay above the zoomed content.

Could we solve this differently? Instead of overloading the position property with new values – such as device-fixed, visual-viewport-fixed, … – could we extend its syntax and provide the viewport as an extra argument? I’m thinking of:

  • position: fixed / layout = current behavior, would be the same as position: fixed)
  • position: fixed / visual = fixed against the visual viewport, also when zoomed in
  • position: fixed / fixed (* lacking a better name) = the proposed behavior from Option 5 (PosFixedViewport)

With this:

  1. The behavior of position: fixed would not be changed, making the adjustments backwards compatible
  2. Authors can feature detect the new behavior and act upon that
  3. Authors can also stick something against the Visual Viewport.

Either way, I think we should definitely adjust Chrome on Android to no longer resize the ICB when the OSK gets shown. This can be implemented separately from the outcome here.

(Also see the Visual Viewport Units from #7194 that would play nice with position: fixed / visual)

@flackr
Copy link
Contributor Author

flackr commented Jul 13, 2022

  1. This would alter the existing behavior of position: fixed on all iOS browsers + Chrome on CrOS. This demo here – which mimics a bottom navigation bar – for example would no longer work as the author expected it to work. This will annoy authors.

You proposed no longer resizing the ICB on Android (without this reinterpretation), which would have the opposite effect of annoying authors who are currently expecting the bottom bar to stay visible wouldn't it? We will be annoying some group of users when we align the keyboard behavior, right? Do you think that users who wanted the bottom / top bar sometimes obscured by the keyboard will be greater in number / more annoyed than the users who didn't? My expectation was that more devs would have expected fixed pos elements to stay visible (the Android behavior) and that changing the default fixed behavior to no longer do that would be more annoying.

Note that a developer could build the old behavior with navigator.virtualKeyboard.overlaysContent = true when iOS adds support for this.

  1. Authors cannot easily feature detect wether the new or old behavior is being used. Therefore they cannot predict how the site will look with the OSK shown. This will annoy authors as well.

If we launch this change in coordination with no longer resizing the ICB, there will generally be no visual change for developers. Whereas if we don't, there will be. This does risk annoying developers on iOS / ChromeOS but they would also currently be annoyed by the Android behavior. The navigator.virtualKeyboard.overlaysContent allows developers to design their own consistent behavior though it is admittedly not yet supported on iOS.

  1. This does not provide a solution for authors to stick something against the Visual Viewport, something that might come in handy for Floating Action Buttons or Toolbars which do need to stay above the zoomed content.

Presumably this is the device-fixed (option 3) in the above list, right? I.e. not changing with zoom. I do think that this is valuable. My main concern is that device-fixed is not the right behavior for bottom-bars, so even if we add it, it does not solve the bottom-bar issue. I do think device-fixed may be independently valuable even though it does have accessibility concerns.

Could we solve this differently? Instead of overloading the position property with new values – such as device-fixed, visual-viewport-fixed, … – could we extend its syntax and provide the viewport as an extra argument? I’m thinking of:

  • position: fixed / layout = current behavior, would be the same as position: fixed)
  • position: fixed / visual = fixed against the visual viewport, also when zoomed in

To be clear, is this option 3 or option 4?

  • position: fixed / fixed (* lacking a better name) = the proposed behavior from Option 5 (PosFixedViewport)
  1. The behavior of position: fixed would not be changed, making the adjustments backwards compatible

We will be changing the position: fixed behavior with the no longer resizing the ICB change, which is not backwards compatible on Android without an update to their behavior.

  1. Authors can feature detect the new behavior and act upon that

You could feature detect this when the keyboard is shown by comparing the height of 100% fixed to the viewport. Alternately the virtualKeyboard API lets developers opt into alternate treatments.

  1. Authors can also stick something against the Visual Viewport.

Agreed, this is an independently useful feature - but not the best for bottom-bars.

@bramus
Copy link
Contributor

bramus commented Jul 13, 2022

You proposed no longer resizing the ICB on Android (without this reinterpretation), which would have the opposite effect of annoying authors who are currently expecting the bottom bar to stay visible wouldn't it? We will be annoying some group of users when we align the keyboard behavior, right? Do you think that users who wanted the bottom / top bar sometimes obscured by the keyboard will be greater in number / more annoyed than the users who didn't? My expectation was that more devs would have expected fixed pos elements to stay visible (the Android behavior) and that changing the default fixed behavior to no longer do that would be more annoying.

By changing the ICB behavior on Android we will already annoy authors as 100vh will behave differently in case the OSK gets shown when compared to the current behavior. Sites that rely on Viewport Units – wether they use position: fixed or not – will be affected by this. Thanks to this ICB change, though, we can achieve interop between browsers and platforms. This is good for authors, as they can from then on reliably know that their code will behave similarly on all browsers and platforms (both 100vh and position: fixed)

By then adjusting how position: fixed is interpreted – which is proposed in Option 5 (PosFixedViewport) – we would break the just-achieved interop. This seems like a step back, especially since authors can’t easily know wether the browser that’s being used, uses the old or the PosFixed behavior. We would also require all other vendors to implement this change, which might not happen.

Therefore I suggested another route to get to the same result. One where the existing behavior position: fixed remains in place (which is: lay items out against the LVP), but where we extend position: fixed with a few new options.

Note that a developer could build the old behavior with navigator.virtualKeyboard.overlaysContent = true when iOS adds support for this.

This assumes that browsers adopt both the adjusted position: fixed behavior and ship the VirtualKeyboard API, and preferably land these at the same time for author convenience.

If the VirtualKeyboard API does not land, then the adjusted position: fixed would make positioning something against the Layout Viewport bottom impossible (without any hackery)

/* Assumes adjusted behavior from Option 5 */
.fab {
  position: fixed;
  bottom: 0; /* Above the OSK */
}

.bottombar {
  position: fixed;
  bottom: ???; /* How can this be positioned against the Layout Viewport? */
}

Looking at WebKit/standards-positions#16 and mozilla/standards-positions#531, there seems to be little excitement for the VirtualKeyboard API.

  1. Authors cannot easily feature detect wether the new or old behavior is being used. Therefore they cannot predict how the site will look with the OSK shown. This will annoy authors as well.

If we launch this change in coordination with no longer resizing the ICB, there will generally be no visual change for developers. Whereas if we don't, there will be. This does risk annoying developers on iOS / ChromeOS but they would also currently be annoyed by the Android behavior. The navigator.virtualKeyboard.overlaysContent allows developers to design their own consistent behavior though it is admittedly not yet supported on iOS.

The “no visual change” you mention would only affect Android. There would still be a difference between Android and non-Android, where we would be dependent on other vendors to achieve interop.

My main concern here was to give authors an easy way to detect wether the current browser has the old or new system implemented. With easy feature detection I mean something like an @supports() rule. No JS.

By introducing the Fixed Viewport this is not possible. By introducing extensions to position: fixed it is as easy as this:

@supports(position: fixed / fixed) {
  /* Yay, new position mechanism available! */
}

As the alternative proposal aligns all browsers initially, and authors can detect the new behavior, they know for sure where which elements will appear.

.fab {
  position: fixed;
  bottom: var(--bottom-bar-height); /* Above the bottombar */
}

.bottombar {
   height: var(--bottom-bar-height);
   position: fixed;
   bottom: 0; /* At bottom of LVP */
}

@supports(position: fixed / fixed) {
  .fab {
    position: fixed / fixed; /* Lay me out against the Fixed Viewport instead of the Layout Viewport */
  }
}

In this snippet, the FAB will be obscured by the OSK on platforms that do not support the new mechanism (cfr. what iOS already does). Authors also know it will be above the OSK in case the browser supports the new behavior. It’s about predictability, instead of being reliant on the progress browser vendors make implementing it.

  1. This does not provide a solution for authors to stick something against the Visual Viewport, something that might come in handy for Floating Action Buttons or Toolbars which do need to stay above the zoomed content.

Presumably this is the device-fixed (option 3) in the above list, right? I.e. not changing with zoom. I do think that this is valuable. My main concern is that device-fixed is not the right behavior for bottom-bars, so even if we add it, it does not solve the bottom-bar issue. I do think device-fixed may be independently valuable even though it does have accessibility concerns.

I’m thinking of Option 4 (scaled device-fixed) here. A side-effect of this option is that these elements might obscure content of the page as the user pinch-zooms in. To limit their “zoomability”, the Visual Viewport Units can be used: by applying something like max-height: 20vvh; width: 100vvw; the element will take up the whole width and at most 20% of the visual viewport height as you pinch-zoom.

I initially considered Option 3 _(device-fixed), but found it a bad idea as it’s hard to grasp the sizing.

  • Say you have a regularly positioned element that has a width of 100vw and you then pinch-zoom in. That element will have grown visually. A position: device-fixed element with the same width set however won’t have grown. Seeing two elements with the same declared width but a different rendered width is pretty confusing.
  • Applying a width of 100vvw a position: device-fixed element would also be pretty confusing: when pinch-zooming in the Visual Viewport shrinks, so those elements would also shrink as you perform the pinch-zoom.

Could we solve this differently? Instead of overloading the position property with new values – such as device-fixed, visual-viewport-fixed, … – could we extend its syntax and provide the viewport as an extra argument? I’m thinking of:

  • position: fixed / layout = current behavior, would be the same as position: fixed)
  • position: fixed / visual = fixed against the visual viewport, also when zoomed in

To be clear, is this option 3 or option 4?

Option 4 (scaled device-fixed)

  • position: fixed / fixed (* lacking a better name) = the proposed behavior from Option 5 (PosFixedViewport)
  1. The behavior of position: fixed would not be changed, making the adjustments backwards compatible

We will be changing the position: fixed behavior with the no longer resizing the ICB change, which is not backwards compatible on Android without an update to their behavior.

As mentioned earlier main perspective on this is an interop one, so that we can make things consistent and predicable for authors.

  1. Authors can feature detect the new behavior and act upon that

You could feature detect this when the keyboard is shown by comparing the height of 100% fixed to the viewport. Alternately the virtualKeyboard API lets developers opt into alternate treatments.

This feels complicated and hacky. A pure CSS solution – using @supports() – is a much nicer solution.

  1. Authors can also stick something against the Visual Viewport.

Agreed, this is an independently useful feature - but not the best for bottom-bars.

The use-case I had in mind are interfaces that sport floating toolbars that need to stay in place as the user zooms in on the content. Sizing and positioning those toolbars using the Visual Viewport Units would make them unzoomable (or give them a limited zoom)

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed viewport positioning vs virtual keyboard.

The full IRC log of that discussion <fantasai> Topic: viewport positioning vs virtual keyboard
<fantasai> github: https://github.com//issues/7475
<fantasai> flackr: [presents the issue]
<fantasai> flackr: Developers want a way to position content that stays in view above a virtual keyboard as it slides into place
<fantasai> flackr: on iOS and ChromeOS this doesn't work today because the virtual keyboard that slides into place changes the visual viewport but not the layout viewport
<fantasai> flackr: You can seen an example here
<fantasai> flackr: the header/footer are clipped and slightly out of view
<fantasai> flackr: behavior on Android today is that we reisze the page
<fantasai> flackr: but this is something that we would like to not do
<fantasai> flackr: just that there has been strong demand for this use case
<fantasai> flackr: there has been a prior suggestion to have a position called device-fixed
<fantasai> flackr: my understanding of how it works is that device-fixed content is outside of pinch-zoom
<fantasai> flackr: and effectively part of the visual viewport
<fantasai> flackr: what we dislike about this is that it's not accessible
<fantasai> flackr: because you can't pinch-zoom this content
<fantasai> flackr: one alternative is scaling the content with pinch-zoom
<fantasai> flackr: but then such content starts massively intruding on the visual viewport
<fantasai> flackr: so what we'd like to propose doing
<iank_> its also quite common for the whole page/app to be within a position:fixed element.
<fantasai> flackr: is defining a viewport that just excludes the virtual keyboard
<fantasai> flackr: but is different from the layout viewport
<fantasai> flackr: so we don't have to do a global reflow when the virtual keyboard shows
<fantasai> flackr: this keeps your headers and footers in position
<fantasai> flackr: you can still zoom around
<fantasai> flackr: this is pretty similar to the effect on android right now with the exception of not changing the actual content layout size
<fantasai> flackr: so we think that it should be Web-compatible for the way that sites exist
<bramus> q+
<fantasai> flackr: unsure about iOS
<fantasai> flackr: I think bramus prefers to move towards iOS behavior
<Rossen_> q+\
<Rossen_> ack \
<Rossen_> q+
<fantasai> bramus: In general, of all these proposals, 5th is what Robert is suggesting
<fantasai> bramus: and I'm in favor
<fantasai> bramus: but I'm not in favor of changing how current position: fixed works
<fantasai> bramus: to counter that, I was thinking of extension to position:fixed
<Rossen_> ack bramus
<fantasai> bramus: where you can specify which viewport you are targetting
<fantasai> bramus: so default is fixed against the layout viewport
<fantasai> bramus: but you would also have options to lay out against the visual viewport
<fantasai> bramus: so that when keyboard is shown ....
<fantasai> bramus: third option is position fixed fixed, positioned against the unzoomed visual viewport
<fantasai> bramus: which is what robert described as option 5
<fantasai> flackr: that's developer optining into either 5 or 4
<fantasai> bramus: the main reason I'm thining along that line is that we wouldn't suddenly change something depending on which platform you're on
<fantasai> bramus: but main advantage to extension to position: fixed syntax is that you can feature-detect
<fantasai> iank_: What's the behavior on Android today?
<fantasai> bramus: what we do right now on Anrdoid is that the layout viewport gets resized when you show a virtual keyboard
<fantasai> bramus: demo on screen
<fantasai> iank_: there's a difference also between position:absolute into ICB vs position:fixed
<fantasai> iank_: what's the difference there again?
<fantasai> flackr: position:fixed lays out against the ??? viewport
<TabAtkins> fantasai: one problem i've often encountered is the heades and footers respond to the position of th ekeyboard, and i'm trying to type into something and i can't see it anymore, bc there's not enough space left
<TabAtkins> fantasai: I'd like for us to not have this problem happen by default
<Rossen_> ack fantasai
<TabAtkins> fantasai: I think visual viewport isn't what we're targeting; again pinch-zoom must not be responded to
<flackr> +1
<TabAtkins> fantasai: what we want is remaiing space after we remove virtual keyboard
<TabAtkins> bramus: rob has been using 'unzoomed virtual viewport'
<TabAtkins> flackr: suggested calling it fixed viewport
<TabAtkins> fantasai: hard not having webkit here, but i recall explaining this as two ways to handle virtual keyboard
<bramus> s/virtual/visual/
<flackr> qq+
<TabAtkins> fantasai: one the keyboard takes up space, another it floats over the content
<TabAtkins> fantasai: i think they follow the floating model
<TabAtkins> fantasai: so the way keyboard interacts is probably affected by that choice
<TabAtkins> fantasai: i think having a special 'fixed viewport' for when you want to attach something to the keyboard or remaining space is reasonable, but i dont' think it shoudl be default
<Rossen_> ack flackr
<Zakim> flackr, you wanted to react to fantasai
<fantasai> flackr: The first behavior I demoed, keyboard floating overtop content, is iOS keyboard
<TabAtkins> flackr: the behavior i demo'd is the behavior iOS has, where effectively the keyboard is floating. it does shrink visual viewport but otherwise doens't affect anything
<fantasai> flackr: option 5 is the same, except you have a viewport that is remaining space
<iank_> q+
<Rossen_> ack Rossen
<fantasai> bramus: and not affected by pinch zoom
<fantasai> Rossen_: Generally speaking, 2 main use cases are iterated have to do with in-page UI that wants to behave more or less close to the way external host UI appears or disappears or behaves
<fantasai> Rossen_: whether this is a keyboard or navbar or search bar
<fantasai> Rossen_: these various permutations are places we want to target
<fantasai> Rossen_: and to push the use cases a little further
<fantasai> Rossen_: as the UI animates in and out, you want to make sure that your stuff animates smoothly with it
<fantasai> Rossen_: this is where device-fixed ideas came in the past
<fantasai> Rossen_: we had a prefixed implementation of this back in the Edge platform where we used position:fixed for UI in PWAs and web apps
<fantasai> Rossen_: in windows
<fantasai> Rossen_: That worked pretty well, but it had the flaw pointed out that they don't zoom in and out with the page
<fantasai> Rossen_: which is exactly what you want, because you're trying to behave closer to the way this native UI behaves
<fantasai> Rossen_: pushing things slightly further, we proposed at some point as part of a larger proposal
<fantasai> Rossen_: a different way of dealing with this which was to expose an environment variable for where the folds are, the top or the bottom folds of the device
<bramus> s/and not affected by pinch zoom/and its sizing not affected by pinch zoom/
<fantasai> Rossen_: I recall a discussion in IIRC Coruña that was extending this further
<fantasai> Rossen_: maybe it was presented by jensimmons at the tme
<Rossen_> https://github.com//issues/4736
<fantasai> Rossen_: that proposal to me was the one that was solving a lot of what was being described here
<fantasai> Rossen_: my question is, there has bene a lot of work and thinking happening here over past 3-4 years
<fantasai> Rossen_: and yet, i'm surprised we're going back to trying to reinvent this
<fantasai> Rossen_: rather than collecting all of the thinking and getting a path forward
<fantasai> Rossen_: Rob or Bramus, was this approach considered or considered and not deemed appropriate or...? what happened?
<Rossen_> q?
<fantasai> flackr: In WICG there's an overlays flag
<fantasai> flackr: you get an environment variable for the size of the keyboard
<fantasai> flackr: the developer is picking up the complexity of where the keyboard should be
<fantasai> flackr: up to them to do the right thing in response to keyboard showing
<fantasai> Rossen_: that seems another permutation of what we're discussing
<fantasai> flackr: that is something shipping in Chrome but not any other browser
<fantasai> flackr: but has complexities because, e.g. you can't scroll to the bottom of the page
<fantasai> flackr: because the keyboard is not considered in your page layout at all
<fantasai> flackr: unless you look to see, how much of the page is my keyboard obscuring
<fantasai> bramus: it also doesn't resize the visual viewport
<fantasai> flackr: that's a bug
<fantasai> Rossen_: I think we should also consider the other discussion of some of the environment variable sand how they play
<fantasai> Rossen_: desire to account for scrollbar etc.
<fantasai> flackr: I have considered some of this, and the initial thinking was that it is complex to do the right thing
<fantasai> flackr: to take all of this into account as a developer
<fantasai> flackr: we wanted to have an easy thing for devs to use, to handle most of the use cases
<fantasai> Rossen_: every time we want to expose a new unit, that's a last step
<fantasai> fantasai: we already rejected that
<fantasai> fantasai: that's not the discussion here
<fantasai> flackr: what's being proposed here is either new positioning scheme or re-intepreting 'position: sticky'
<fantasai> fantasai: sticky?
<fantasai> flackr: we would need to also address sticky, ensure those are still in view
<fantasai> fantasai: I understand wanting that to work... but also... I see so many pages that assume there'll be enough space left and there isn't space to see what I'm typing into
<fantasai> Rossen_: This is why my preference is for this environmental awareness is better expressed in environment variables which you can add to your calc() expressions
<fantasai> Rossen_: and then can improve UI clutter depending on how much space you have left
<fantasai> Rossen_: with positoin, you have to work backwards to see how large it lays out, and then if you don't like it go back and remove it
<fantasai> Rossen_: much heavier option
<flackr> Something like position: fixed; bottom: env(keyboard-height); ?
<fantasai> Rossen_: would much rather do a conditional on a calc() expression and do everything pre-layout
<fantasai> Rossen_: would prefer to do that pre-layout to decide if element continues to be there or not
<fantasai> Rossen_: for example, but can do more than that?
<fantasai> fantasai: Curious what Rossen means by "do more"
<fantasai> fantasai: but also, wrt that example, we would want insets from each edge of the screen, similar to the safe-area insets
<fantasai> Rossen_: what you just described. Need all 4 sides
<emilio> q+
<fantasai> flackr: One complication with that
<fantasai> flackr: right now adding keyboard inset to the bottom work, but I pan down it's at layout viewport plus keyboard height
<fantasai> bramus: if something is position: fixed; bottom: keyboard-height, it would obscure ???
<fantasai> bramus: because you aren't taking the offset of the visual viewport measured against the layout viewport into account
<fantasai> Rossen_: ...
<fantasai> iank_: One quick thing, rob, I'm assuming that any proposal
<fantasai> iank_: we're going to be compat-constrained on Android pretty heavily
<Rossen_> s/.../not if we are exposing the insets env values/
<fantasai> iank_: because ppl are relying heavily on our current behavior
<fantasai> flackr: we have a lot of interop differences, e.g. iOS vs Android
<fantasai> iank_: yes, but ppl know this and have written code to make it work on each platform
<fantasai> flackr: I suspect that's true
<bramus> q?
<fantasai> iank_: I just wanted to make one thing clear, we're in a very sucky position here
<fantasai> iank_: but I don't think that Android or Android webview would be able to change behavior here
<fantasai> iank_: same with iOS
<Rossen_> ack iank_
<Rossen_> ack emilio
<fantasai> (basically, we are doomed to non-interop?)
<fantasai> emilio: At a glance, from my phone, ?? behae like Chrome and Firefox
<fantasai> emilio: resizes and fixes stuff
<fantasai> emilio: the problem with iOS behavior is can you even see something at the bottom of the page?
<fantasai> flackr: when you pan, you're moving the visual viewport and can scroll to the bottom of the page
<fantasai> iank_: I think it's still true that there are various tricks ppl do to get it to autoscroll down into that position
<fantasai> flackr: When you focus an input, it scrolls into view, and that moves the visual viewport
<fantasai> iank_: but ppl exploit various tricks on iOS to get the visual viewport to scroll to the end of the layout viewport
<fantasai> bramus: tricks I've seen ppl use is to steer away from the behavior where the browser automatically tires to center the input into the visual viewport
<Rossen_> q?
<Rossen_> another relevant topic to review is https://github.com//issues/1693
<fantasai> flackr: the reason you can get to the bottom is the browser knows the size of the keyboard and shrinks the visual viewport by that amoutn so you can scroll that much extra
<fantasai> emilio: do stuff like ??? on iOS, on the keyboard, presumably their inputs fix to the top fo the keyboard right?
<fantasai> emilio: like Anrdoid is doing right now
<fantasai> emilio: On one hand I get that it's nice to not resize the layout viewport
<fantasai> emilio: but something like either your proposal, which is fine, or current android/chrome proposa, seems more towards what authors want
<bramus> q+
<fantasai> emilio: when is the iOS behavior preferable right now?
<flackr> +1
<fantasai> emilio: when you have iOS app, if it behaves like Android
<fantasai> Rossen_: you have to do all kinds of funky UA detection stuff
<fantasai> flackr: native apps behave like ???
<fantasai> emilio: they behave like Chrome/Firefox
<fantasai> flackr: option 5 was designed to be more like native app behavior
<fantasai> bramus: what I like about proposal is that it allows authors to have both behaviors
<fantasai> bramus: so if author wants bottom bar not affected by showing keyboard, can get that
<Rossen_> ack bramus
<fantasai> bramus: should they want android behavior, authors can also retain the existing behavior by doing feature detection
<iank_> does the proposal allow Android & iOS to keep the current default behaviour?
<fantasai> bramus: but would require landing both changes on Android at the same time
<flackr> qq+
<fantasai> bramus: so authors can choose to have something at the bottom bottom, or above the on-screen keyboard
<fantasai> iank_: does someone have an existing PWA, we're not changing default behavior?
<fantasai> bramus: Twitter app
<fantasai> flackr: what are you proposing the default is?
<fantasai> bramus: default would be to have position:fixed as before, lay out items against the outer viewport
<fantasai> bramus: that would be the iOS behavior
<fantasai> iank_: we can't do that
<Rossen_> q?
<Rossen_> ack flackr
<Zakim> flackr, you wanted to react to bramus
<fantasai> flackr: bramus brought about customizing behavior
<fantasai> flackr: the virtual keyboard overlays content behavior allows complete customization of the bheavior
<fantasai> flackr: if you're a site that wants to customize ythe behavior, you can do that
<fantasai> flackr: this is more about having sensible defaults that work well
<fantasai> Rossen_: So, let's figure out some next steps
<fantasai> Rossen_: most of the conversation seems to be circling around the option 5 that you proposed
<fantasai> Rossen_: we cna record that this is the current preferred method
<Rossen_> ack fantasai
<TabAtkins> fantasai: bramus was suggesting there be various syntactic ways of opting into different behaviors
<TabAtkins> fantasai: i think this is something that, if we want to add it, it shoudl be an independently cascade property from position
<TabAtkins> fantasai: likely you'll think abuot how your stuff adapts at a different level from how it's laid out
<TabAtkins> fantasai: so it should be a different prop
<TabAtkins> fantasai: position:fixed, and a "fixed-to:whatever" prop
<fantasai> s/different/independently cascading/
<fantasai> Rossen_: do we need to take any resolution on these proposals?
<fantasai> flackr: We would like to get more feedback
<fantasai> Rossen_: seems we've clearly indicated favorable options, should be easier to page in next time
<fantasai> I also wonder if we want to do this *and* have the environment variables

@fantasai
Copy link
Collaborator

There's some useful discussion of use cases in #7194 btw.

@bramus
Copy link
Contributor

bramus commented Jul 20, 2023

Had a breakout session with @smfr at the 2023 Cupertino F2F. In summary, two concerns were raised:

  • Landscape Mode: there is almost no room left above the keyboard, so we should be cautious here.
  • In the scenario where a user first pinch-zooms and then bring up keyboard, a FixedPos element can suddenly jump into view because the PosFixedViewport shrinks.

Furthermore, the default behavior we have right now should preferably not be changed, and it should be an opt-in indeed.

@flackr
Copy link
Contributor Author

flackr commented Jul 21, 2023

Furthermore, the default behavior we have right now should preferably not be changed, and it should be an opt-in indeed.

We currently don't have interop though right? I think ideally one of the current behaviors would change.

@una
Copy link
Contributor

una commented Feb 8, 2024

I like this idea, being able to specify where something is fixed, but I would propose a function syntax, like fixed(visual-viewport). This would make it more clear that this is an argument for where you are applying the positioning algorithm. The/ syntax reminds me of positioning that breaks out two directions (i.e. block and inline as in grid). It would also be neat to be able to reference names areas here! I.e. fixed(--area)

@ryantownsend
Copy link

Forgive me for jumping in with a comment without having read the full thread above, but @bramus asked me to add a use-case I have for honouring both the visual viewport and layout viewport on a single page.

I’ve pinned a cookie/marketing consent banner to the bottom of the viewport, it’s a non-modal dialog (could probably replace with popover now) that allows the user to interact with the rest of the page without being forced to interact with it (because I’m nice like that).

Then I have other elements that I need to keep above the soft keyboard, for example a ‘view all results’ button for a typeahead search – I want this pinned to the bottom of the visual viewport at all times, whereas the cookie banner can be hidden behind the keyboard as it would get in the way of typeahead (and thus defeat my objective to keep it unobtrusive).

This currently seems impossible with Chrome’s meta tag implementation as you can only choose one behaviour at a document-level. My suggestion on Mastodon was that we could do this if there were a ‘vvh’ CSS unit (‘visual viewport height’), then it would be up to the CSS author to decide where to apply this unit to make adjustments, rather than something layout-based living outside in HTML (meta) or JS events.

I’m currently relying on the visual viewport resize event which is less than ideal for a whole bunch of reasons I’m sure everyone here is aware of.

@bramus
Copy link
Contributor

bramus commented May 2, 2024

While Visual Viewport units have already been rejected – see #7194 – the reinterpretation/extension to position fixed from this issue could help out here.

You could bottom anchor the one thing the layout viewport and the other to the (unzoomed) visual viewport.

@ryantownsend
Copy link

@bramus position: fixed / [fixed/visual] seems sensible, but to avoid dependence on knowing the height of elements in my example, it would be useful to extend this option by also introducing position: sticky / [fixed/visual], otherwise we'd be forever needing to bottom-pad the container with the height of the floating element – which is doable but far less maintainable/responsive.

@ryantownsend
Copy link

Having now read more of the above thread, has a ‘zoomed’ media query been suggested/considered?

If there are concerns with an FAB dominating the viewport when zoomed or performance being impacted when evaluating viewport units during zoom, maybe a boolean-, threshold- or step-based media query could be a compromise?

e.g. @media (1 < zoom-level < 2) (greater than 100%, less than 200%), akin to the level 4 width queries

@media (zoom-threshold: 2) – more basic threshold

@media (zoomed: true) - most basic boolean.

(Note: I’m suggesting only one of these would be implemented, they just have varying degrees of complexity)

This would present a multitude of options to authors, e.g. with any of the above, we could opt to only pin while the viewport remains unzoomed:

@supports (position: fixed / fixed) {
  @media not (zoomed: true) {
    .fab { position: fixed / fixed }
  }
}

With zoom-level, we could adjust sizes for different zoom levels:

@supports (position: fixed / fixed) {
  .fab { position: fixed / fixed }

  @media (zoom-level > 1) {
    .fab { font-size: 0.8em }
  }

  @media (zoom-level > 2) {
    .fab { font-size: 0.6em }
  }
}

@waterplea
Copy link

It's pretty crazy that in 2024 we still cannot show an always visible floating action button at the bottom of the screen with CSS, regardless of screen keyboard being present or not. That's a very needed feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-position-3 Current Work
Projects
Status: Wednesday
Development

No branches or pull requests

9 participants