iOS 15 固定位置、全屏内容的最小化地址栏问题

iOS 15 minimized address bar issue with fixed position, full screen content

使用iOS 15.0.2 Safari,当屏幕键盘关闭时,地址栏可以最小化而不更新视口高度。这会导致在不按地址栏的情况下无法移除底部间隙。是否有任何已知的解决方法?通过使用嵌套容器,可以在没有任何设备旋转的情况下达到这种状态,但我能想到的最简单的可重现示例如下:

  1. 旋转到横向
  2. 专注于文本输入以调出屏幕键盘
  3. 旋转到纵向
  4. 按屏幕键盘上的“完成”

body {
  padding: 0;
  margin: 0;
  overflow: hidden;
  position: fixed;
  inset: 0;
  -webkit-text-size-adjust: 100%;
}
input {
  font-size: 16px;
}
<head>
  <meta name="viewport" content="width=device-width,initial-scale=1, viewport-fit=cover">
  <meta name="theme-color" content="#000000">
</head>
<body>
  <input type="text" />
</body>

我最近遇到了同样的问题,将正文 position 设置为 fixed 以在显示覆盖时阻止滚动。一旦禁用滚动,Safari 就会停止渲染将被展开 iOS UI 覆盖的下部区域,留下与您在屏幕截图中显示的相同的黑条。

将正文设置为 position: fixed 时将 html.style.height 设置为 100vh 似乎可以解决问题。

我构建了一个简单的示例页面,您可以在其中看到不同之处。 打开页面后,您必须向下滚动一点,找到折叠 Safari 的按钮 UI。然后您可以通过单击按钮切换 position: fixedcode-to-fix-error class(以修复错误)。

在我的滚动阻塞示例中: 将 height 设置为 calc(100vh - 1px) 也会在弹出窗口处于活动状态时阻止 safari 原生橡皮筋/弹性滚动效果。此更改应仅应用于 iOS 设备。

const btnError = document.querySelector('button.error')
btnError
  .addEventListener('click', () => {
    btnError.innerHTML = document.documentElement.classList.toggle('code-to-fix-error')
      ? 'Fix active'
      : 'Fix inactive'
  })

let y = 0
const btnToggle = document.querySelector('button.toggle')
btnToggle
  .addEventListener('click', () => {
    const _doc = document.documentElement
    if (_doc.classList.contains('active')) {
      _doc.style.setProperty('--scroll-y', `0`)
      _doc.classList.remove('active')
      window.scroll(0, y)
      btnToggle.innerHTML = 'position: static'
    } else {
      y = window.scrollY
      _doc.style.setProperty('--scroll-y', `-${y}px`)
      _doc.classList.add('active')
      btnToggle.innerHTML = 'position: fixed'
    }
  })
body {
  padding: 400px 0 0 0;
  margin: 0;
  inset: 0;
  -webkit-text-size-adjust: 100%;
  background-color: #435283;
  text-align: center;
  height: 8000px;
  width: 100%;
}

html.code-to-fix-error.active  {
  height: 100vh;
}

html.active body {
  top: var(--scroll-y);
  overflow: hidden;
  position: fixed;
}

button {
  appearance: none;
  line-height: 30px;
  padding: 0 10px;
  background-color: #FFF;
  color: #435283;
  border-radius: 3px;
}
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1, viewport-fit=cover">
    <meta name="theme-color" content="#000000">

    <style>/* styles here */</style>
  </head>
  <body>
    <button class="error">Fix inactive</button>
    <button class="toggle">position: static</button>
    
    <style>/* script here */</style>
  </body>
</html>