你还在为虚拟键盘适配苦恼吗,虚拟键盘API即将到来,快来看看吧

转载说明:原创不易,未经授权,谢绝任何形式的转载

开篇

你是否遇到过一个问题,即在移动设备上有一个固定元素,当键盘激活时,该元素会被键盘遮挡?这已经是多年来网络上的默认行为了。在本文中,我们将探讨这个问题,为什么会发生这种情况,以及如何使用虚拟键盘API来解决它。让我们开始吧。

问题

在深入细节之前,让我们通过一个例子来了解一下。这是一个具有以下内容的用户界面:

当用户将焦点放在输入框上时,虚拟键盘将会显示出来。你能预料到会发生什么吗?

浏览器将向上滚动以使输入框在键盘上方,因此粘性标题和浮动按钮将消失。

它看起来与以下内容相似:

这是移动浏览器中的默认行为。从用户体验的角度来看,隐藏部分用户界面可能会很烦人,特别是那些与当前正在进行的操作相关的部分,而此时键盘是激活状态。

幕后发生的事情类似于下图所示。

在技术术语中,可见部分被称为视口,而隐藏部分以及当前可见的部分则是布局视口。

主要问题是当虚拟键盘激活时,可视视口的大小会缩小。

使用虚拟键盘API修复键盘下隐藏的内容

由于虚拟键盘API的存在,我们可以定义视觉和布局视口相等。通过这样,我们可以使用以下CSS环境变量来检测键盘的位置和尺寸:

通过使用上述变量,我们可以在虚拟键盘激活时修改布局。

Browser Support 浏览器支持

在撰写本文时,VirtualKeyboard API仅在Chrome for Android中受支持。在下一部分中,我将探讨一些例子和使用情况,以展示它的帮助性。

启用虚拟键盘API

此 API 默认不可用。我们需要使用 JavaScript 来启用它。请看下面的内容:

if ("virtualKeyboard" in navigator) {
  navigator.virtualKeyboard.overlaysContent = true
}

我觉得这有点奇怪,使用JavaScript来实现这样的行为。我同意Bramus在他的文章中对这个话题的看法。他建议使用类似这样的meta标签:


或CSS属性:

html {
  virtual-keyboard: overlays-content;
}

更新:2023年8月2日

Bramus友好地指出,在viewport meta标签中有一个新的 interactive-widget ,可以帮助改变调整大小的行为。

请参阅MDN获取详细信息。

https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#interactive-widget

我尝试在安卓的Chrome浏览器(版本113)上进行测试,但是没有成功。我会在了解更多信息后更新这篇文章。

VirtualKeyboard API 的使用案例

底部固定操作

在较小的视口上,您可能需要一个固定在界面底部的呼叫行动按钮或页脚。

考虑下面的图示,我们有一个固定在底部的CTA按钮。屏幕中间有一个输入框。

当输入框处于活动状态时,结账按钮将位于虚拟键盘下方,因此被隐藏起来。

我们可以轻松地通过虚拟键盘API来解决这个问题。

input {
  font-size: 16px;
}
.cta {
  bottom: env(keyboard-inset-height, 0);
}

在移动设备上, bottom 的值将等于键盘的高度,从而将CTA按钮偏移相应的值。如果浏览器不支持该API,则会默认为 0。

你可能会对由于标题和固定底部的存在而导致的空间减少感到困惑。我们可以使用垂直媒体查询来在垂直空间足够的情况下显示标题。

无法滚动到页面的最底部

当视口底部有一个带有 position: fixed 的项目时,我们通常会添加 padding-bottom 来偏移页面,使用户可以滚动到最底部。

body {
  --cta-height: 60px;
  padding-bottom: var(--cta-height);
}

.cta {
  bottom: env(keyboard-inset-height, 0);
}

padding-bottom 应该是一个等于或大于固定元素高度的值。

酷吧,对吧?当我们加入一个虚拟键盘时会发生什么?让我们来看看。请看下图:

为了更好地展示问题,如下动画所示:

为了解决这个问题,我们需要检测输入是否处于焦点状态,并根据此进行相应的 padding-bottom 更改。

body:has(input:focus) {
  padding-bottom: calc(
    var(--cta-height) + env(keyboard-inset-height, 0)
  );
}

你可能会想知道,在桌面端会发生什么?好问题。 env() 会回退到 0 ,总计将得出 var(--cta-height) 的值。

浮动操作按钮

在这个例子中,我们有一个浮动操作按钮,它位于页面的右下角。

当键盘激活时,浮动按钮应该移动到键盘上方。就像第一个例子中一样,浮动按钮将位于键盘下方。

为了解决这个问题,我们可以使用 env(keyboard-inset-height) 值。

让我们一起来看看解决方案:

.fab {
  /* other styles */
  bottom: calc(1rem + env(keyboard-inset-height, 0rem));
}

我使用 1rem 加上键盘的高度,以避免浮动按钮直接位于键盘顶部边缘。

使用CSS比较函数时,需要注意在 env() 中使用无单位的数字作为回退值会导致在Safari中出现错误。我们必须添加单位 rem 。

为桌面使用不同的值

假设我们想在桌面浏览器上进一步调整浮动按钮的位置,我们该如何做呢?嗯,我考虑使用 max() 比较函数,结果行得通。

.fab {
  /* other styles */
  bottom: max(2rem, 1rem + env(keyboard-inset-height, 0rem));
}

这是它的工作原理:

  1. 比较函数将在两个值之间进行比较。由于 env(keyboard-inset-height) 在桌面上的值为 zero ,所以最大值为 2rem 。
  2. 在移动设备上,最大值是第二个。

聊天布局

我受到了Thomas Steiner在这篇文章中的例子的启发,想要向你展示它是如何工作的。

https://developer.chrome.com/docs/web-platform/virtual-keyboard/

请看下图:

当键盘激活时,标题和消息字段都会隐藏起来。我们可以将 env(keyboard-inset-height) 作为 grid-row 属性的值。

.layout {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto env(keyboard-inset-height, 0);
  height: 100dvh;
}

这是修复后的样子:

明智地使用虚拟键盘API

只有在需要的时候才应该使用虚拟键盘。在每个情境中都使用它可能会引起问题。是的,你没看错。

让我们举个简单的例子。我们有一个联系页面,其中包含长内容和表单输入。如果我们选择让虚拟键盘覆盖页面内容,那么将无法滚动到表单的最后。

在这种情况下,我不建议键盘覆盖内容。明智地使用它。

请观看以下视频以了解问题的感觉:

使用虚拟键盘 API 的比较函数

根据虚拟键盘的可见性来改变按钮的形态

这可能是一个无用的用例或示例,但当一个功能被充分利用时,看到发生的事情是很有趣的。

我心里想,为什么不把CSS比较函数和虚拟键盘的值混合在一起呢?我试了一下,结果还真行。

请查看下面的视频:

这是怎么运作的?给你:

.fab {
  --size: 4rem;
  position: fixed;
  /* [1] */
  right: min(1rem, 100vw - env(keyboard-inset-width, 0rem));
  /* [2] */
  bottom: max(1rem, env(keyboard-inset-height, 0rem));
  /* [3] */
  width: max(var(--size), env(keyboard-inset-width, 0rem));
  height: var(--size);
  /* [4] */
  border-radius: max(
    0px,
    min(50px, 100% - env(keyboard-inset-width))
  );
  /* other styles */
}

这适用于桌面和移动设备。以下是正在发生的事情:

  1. right 的值将是 1rem 或 zero 。前者用于桌面,后者用于移动设备(当键盘激活时)。 100vw 在这种情况下等于键盘的宽度,因此结果为零。 min(1rem, 0) 。
  2. 底部的值将是 1rem 或键盘的高度。
  3. 在桌面尺寸上,宽度等于变量 --size ,而在移动设备上,它将占据整个宽度,因此使用了 env(keyboard-inset-width, 0) 。
  4. 最后, border-radius 可以是 50px 或者 0 。

不错,对吧?我从来没想到能做出这样的演示。你觉得它有用吗?我很期待看到你会做出什么。

Linkedin帖子表单和导航

我看到应用虚拟键盘API的潜力很大的一个例子是LinkedIn帖子的发布表单和导航显示方式。请看下图:

帖子表单和导航固定在底部。当用户激活输入字段时,它会显示如下:

注意垂直空间太小。怎么办?通过混合比较功能和虚拟键盘API,我们可以在键盘显示时隐藏导航。

这是实现此功能的CSS代码。

.post-form,
.nav {
  position: fixed;
  left: 0;
  right: 0;
}

.post-form {
  bottom: max(48px, env(keyboard-inset-height, 0px));
}

.nav {
  bottom: max(0px, env(keyboard-inset-height, 0) - 100px);
}

别担心,我会一点一点地解释。

Post Form 发布表格

在默认状态下,表单与底部相距 48px 。在这种状态下, max() 函数的第二部分是不活动的。

当键盘激活时, max() 的第二部分将起作用, bottom 的值将变为键盘的高度。

Navigation 导航

导航位于 bottom: 0 。 max() 功能的第一部分是当前活动的部分。

当键盘激活时,我们将导航移动到键盘下方。这里的 100px 是一个随机数,重点是添加一个比导航高度更大的元素。

这是一个演示它如何工作的视频:

结束

这就是本文的全部内容。我对虚拟键盘API有了很多了解,迫不及待地想在我的下一个项目中应用它。我最后没想到的是会在这个话题上写4000多字。如果这有什么意义的话,那就是永远不要相信自己对不了解的事物的内心感觉。只要开始行动,好事就会接踵而至。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

展开阅读全文

页面更新:2024-03-01

标签:键盘   下图   表单   苦恼   函数   按钮   例子   高度   桌面   发生   内容

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top