【问题标题】:Safari Viewport Bug, Issues with Fixed Position and Bottom or TopSafari 视口错误,固定位置和底部或顶部的问题
【发布时间】:2019-10-30 13:15:30
【问题描述】:

我在 iOS 12.3.1 Safari 中遇到了一些奇怪的事情。 这个问题至少可以追溯到 iOS 12.2, 但我想这个问题的存在时间要长得多。

在尝试将元素与视口的底轴对齐时会出现此问题,并且在纵向和横向模式下都是一个问题。

为了重现该问题,元素必须具有positionfixedabsolute,但无论您将元素定位为toptransform 还是bottom .

人像模式

该问题仅在纵向模式下表现出来如果 Safari 显示其精简的 URL 栏, 替换了正常的 URL 和菜单栏,并且没有垂直溢出。

普通 URL 和菜单栏 // 压缩 URL 栏

值得注意的是,压缩菜单栏仅在出现垂直溢出并且浏览器向下滚动时或当浏览器的方向从纵向更改为横向然后再返回时才会显示(不管是否存在垂直溢出) )。

垂直溢出改变方向//没有溢出

我不确定这里到底发生了什么。

横向模式

横向模式的问题总是并且仅在正常导航栏显示在页面顶部时才会出现。由于向下滚动或方向从纵向更改为横向,导航栏只会在横向模式下隐藏。

垂直溢出

没有垂直溢出

有趣的是,横向模式下导航栏的高度明显偏移了视口,因此在显示导航栏时bottom: 0top: 100%的位置被推到了视口之外。

纵向模式的糟糕“解决方法”

这是一个超级 hack-ish 的解决方法,也是一个糟糕的解决方法,但这是迄今为止唯一导致 position: fixed; bottom: 0; 在没有溢出的情况下切换方向后将元素实际定位在视口底部的方法。

<div style='height: 0'>
  <!-- the quantity of <br> elements must create vertical overflow -->
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <!-- this does not work without the space character -->
  &nbsp;
</div>

但是,我只是注意到它会产生不可见的垂直溢出,因此至少在 Safari 和 Chrome 中会产生不必要的垂直滚动。我还担心它可能会在其他浏览器中的其他设备上导致我无法测试的其他问题。


由于这个错误,为了用户体验,一个网站有时不得不看起来像垃圾,这真是太糟糕了。

有人知道发生了什么吗?

有人知道任何解决方法吗?

有人知道实际的解决方案吗?

【问题讨论】:

  • 检查stackoverflow.com/a/52936930/5623035是否有帮助并告诉我。
  • @MojtabaHosseini 这个问题看起来非常相似,但它最终是一个不同的问题,尽管它们很可能彼此相关。这些图像中的浏览器本身与我的手机在 12.3.1 中的设备上使用的 Safari 浏览器不同或看起来不同。
  • 图像与嵌入在应用程序中的SFSafariViewController 相关,而不是 Safari 本身。我建议您在那里尝试解决方案,看看是否有帮助,但不能保证。
  • @MojtabaHosseini 我的问题与图像或&lt;img/&gt; 元素完全无关

标签: html css iphone mobile safari


【解决方案1】:

你好,这个问题一开始让我很受启发,我回想起我在 HTML 和 CSS 中花费数小时试图解决问题的日子。唉,所有这些痛苦的时光都是为了这一刻。

vh 曾经由浏览器的当前视口计算得出。如果您在浏览器中加载网站,1vh 将等于屏幕高度的 1%,然后减去浏览器界面。

但是!如果你想滚动,它会变得很棘手。一旦你刷过浏览器界面(在这种情况下是你的地址栏),你的内容会有一个奇怪的跳转,因为 vh 会被更新。

iOS 版 Safari 实际上是最早实施修复的之一。他们根据最大屏幕高度设置了一个固定的vh 值。这样用户就不会体验到内容的跳跃,但是....是的,总有一个但是...

拥有固定值非常棒,除非你想要一个全尺寸元素,或者一个在屏幕底部位置固定的元素,因为那样它就会被裁剪掉!

那是你的问题....和它说再见,因为...

这是你的解决方案!

css:

.my-element {
  height: 100vh; /* This is for browsers that don't support custom properties */
  height: calc(var(--vh, 1vh) * 100);
}

js:

// Get the viewport height and multiply it by 1% to get a value for a vh unit
let vh = window.innerHeight * 0.01;
// Then set the custom --vh value to the root of the document
document.documentElement.style.setProperty('--vh', `${vh}px`);

现在您可以像使用任何其他 vh 单位一样使用 --vh 作为您的高度值,将其乘以 100 即可获得我们想要的完整高度。

还有一点,上面的 js 运行了,但是当视口改变时我们从不更新元素的大小,所以这还行不通,你需要一个监听器...

更多js:

// We listen to the resize event
window.addEventListener('resize', () => {
  // Update the element's size
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
});

干杯!

【讨论】:

  • 天哪,对不起。事实是它不能单独在 html 中完成,因为它是动态的。这里有太多更新视口高度的事情。您需要能够设置变量并能够不断更新它们,因为视口高度受浏览器地址栏的影响。 var 的工作方式也是这样的:“var(自定义值,后备值)”,您可以根据需要添加任意数量。示例:var(自定义值、fallback1、fallback2、fallback3 等)
  • var(--vh, 1vh) 1vh 称为后备或默认值,如果您未指定自定义属性的值或将其设置为初始值(相关:stackoverflow.com/a/55615712/8620333/ stackoverflow.com/a/53239881/8620333)
  • @jreyes 啊不知道你可以设置后备。无论如何,即使您在 Safari 中使用 JS 方法来处理景观,也存在多个问题;如果你向上滚动,它会在元素下方创建一个与 URL 栏大小相同的空白区域。它在 iOS 上的 Chrome 中也有很多问题。这只是在我能够测试的浏览器上。
  • 我搞砸了它试图再次重现问题,但我只能重现其中一个。 heres a screenshot.。如果您向下滑动以显示 URL 栏,似乎会触发 resize 事件,因此它将 var(--vh) 重新计算为 innerHeight 的 1% 减去 URL 栏高度。如果在仍然显示 URL 栏的情况下向上滑动以向下滚动页面,则即使没有可滚动的内容,它也会留下空间并滚动页面。我希望这是有道理的?
  • 不幸的是... innerHeight 在 safari 上也不可靠。当您打开键盘时,它将完全分解。而且 resize 事件也不可靠,它并不总是被触发。黎明许多错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 2011-03-25
  • 2014-06-09
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多