Safari视口错误,位置固定和底部或顶部出现问题

Pri*_*Nom 9 html css iphone safari mobile

我在iOS 12.3.1 Safari中遇到了一些奇怪的事情。这个问题至少可以追溯到iOS 12.2,但是我想这已经是一个更长的问题了。

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

为了重现该问题,该元素必须具备positionfixedabsolute,但它并不重要,你是否该元素具有位置toptransformbottom

人像模式

当Safari显示其压缩的URL栏(代替普通的URL和菜单栏)且没有垂直溢出时,此问题才会以纵向显示

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

在此处输入图片说明 在此处输入图片说明

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

垂直溢出时更改方向//不溢出

在此处输入图片说明 在此处输入图片说明

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

风景模式

横向模式的问题始终且仅在页面顶部显示正常导航栏时才会发生。由于向下滚动或方向从纵向更改为横向,因此导航栏仅在横向模式下处于隐藏状态。

垂直溢出

在此处输入图片说明 在此处输入图片说明

没有垂直溢出

在此处输入图片说明 在此处输入图片说明

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

纵向模式的胡扯“解决方法”

这是一个超级hack的解决方法,也是一个糟糕的解决方法,但这是迄今为止唯一的事情,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>
Run Code Online (Sandbox Code Playgroud)

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


绝对令人讨厌的是,由于此错误,为了用户体验,网站有时有时看起来像废话。

外面有人知道发生了什么吗?

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

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

jre*_*yes 11

你好,这个问题一开始让我很感兴趣,我回想起我在 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);
}
Run Code Online (Sandbox Code Playgroud)

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`);
Run Code Online (Sandbox Code Playgroud)

现在您可以使用 --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`);
});
Run Code Online (Sandbox Code Playgroud)

干杯!

  • 噢,伙计,对不起。事实上,由于 html 的动态特性,它无法单独在 html 中完成。这里有太多关于更新视口高度的事情。您需要能够设置变量并能够不断更新它们,因为视口高度受到浏览器地址栏的影响。此外,var 的工作方式如下:“var(自定义值,后备值)”,您可以根据需要添加任意数量。示例:var(自定义值、fallback1、fallback2、fallback3 等) (2认同)
  • 我弄乱了它以尝试再次重现这些问题,但我只能重现其中一个。[这里有一个截图。](https://i.postimg.cc/pLs03qJW/IMG-0401.png)。如果您向下滑动以显示 URL 栏,似乎会触发 `resize` 事件,因此它会将 `var(--vh)` 重新计算为 `innerHeight` 的 1% 减去 URL 栏高度。如果在 URL 栏仍然显示的情况下向上滑动以向下滚动页面,则会留下空间并滚动页面,即使没有任何内容可滚动。我希望这是有道理的? (2认同)
  • 不幸的是...innerHeight 在 safari 上也不可靠。当你打开键盘的时候它就会彻底崩溃。而且调整大小事件也不可靠,它并不总是被触发。黎明很多错误。 (2认同)