CSS3 100vh 在移动浏览器中不恒定

2022-01-30 00:00:00 html css viewport-units

我有一个非常奇怪的问题...在每个浏览器和移动版本中我都遇到了这种行为:

I have a very odd issue... in every browser and mobile version I encountered this behavior:

  • 所有浏览器在您加载页面时都有一个顶部菜单(例如显示地址栏),当您开始滚动页面时会向上滑动.
  • 100vh 有时仅在视口的可见部分计算,因此当浏览器栏向上滑动时,100vh 会增加(以像素为单位)
  • 由于尺寸发生变化,所有布局都重新绘制和调整
  • 对用户体验的不良影响
  • all the browsers have a top menu when you load the page (showing the address bar for example) which slide up when you start scrolling the page.
  • 100vh sometimes is calculated only on the visible part of a viewport, so when the browser bar slide up 100vh increases (in terms of pixels)
  • all layout re-paint and re-adjust since the dimensions have changed
  • a bad jumpy effect for user experience

如何避免这个问题?当我第一次听说 viewport-height 时我很兴奋,我认为我可以将它用于固定高度的块而不是使用 javascript,但现在我认为唯一的方法实际上是带有一些 resize 事件的 javascript...

How can avoid this problem? When I first heard of viewport-height I was excited and I thought I could use it for fixed height blocks instead of using javascript, but now I think the only way to do that is in fact javascript with some resize event...

您可以在以下位置查看问题:示例网站

you can see the problem at: sample site

谁能帮助我/建议一个 CSS 解决方案?

Can anyone help me with / suggest a CSS solution?

简单的测试代码:

/* maybe i can track the issue whe it occours... */
$(function(){
  var resized = -1;
  $(window).resize(function(){
    $('#currenth').val( $('.vhbox').eq(1).height() );
    if (++resized) $('#currenth').css('background:#00c');
  })
  .resize();
})

*{ margin:0; padding:0; }

/*
  this is the box which should keep constant the height...
  min-height to allow content to be taller than viewport if too much text
*/
.vhbox{
  min-height:100vh;
  position:relative;
}

.vhbox .t{
  display:table;
  position:relative;
  width:100%;
  height:100vh;
}

.vhbox .c{
  height:100%;
  display:table-cell;
  vertical-align:middle;
  text-align:center;
}

<div class="vhbox" style="background-color:#c00">
  <div class="t"><div class="c">
  this div height should be 100% of viewport and keep this height when scrolling page
    <br>
    <!-- this input highlight if resize event is fired -->
    <input type="text" id="currenth">
  </div></div>
</div>

<div class="vhbox" style="background-color:#0c0">
  <div class="t"><div class="c">
  this div height should be 100% of viewport and keep this height when scrolling page
  </div></div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

推荐答案

很遗憾这是故意的……

这是一个众所周知的问题(至少在 safari mobile 中),这是故意的,因为它可以防止其他问题.Benjamin Poulain 回复了一个 webkit 错误:

This is a well know issue (at least in safari mobile), which is intentional, as it prevents other problems. Benjamin Poulain replied to a webkit bug:

这完全是故意的.我们花了相当多的工作来达到这个效果.:)

This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)

基本问题是:可见区域会随着滚动而动态变化.如果我们相应地更新 CSS 视口高度,我们需要在滚动期间更新布局.这不仅看起来很糟糕,而且在大多数页面中以 60 FPS 的速度做到这一点实际上是不可能的(60 FPS 是 iOS 上的基准帧速率).

The base problem is this: the visible area changes dynamically as you scroll. If we update the CSS viewport height accordingly, we need to update the layout during the scroll. Not only that looks like shit, but doing that at 60 FPS is practically impossible in most pages (60 FPS is the baseline framerate on iOS).

很难向您展示看起来像狗屎"的部分,但想象一下,当您滚动时,内容会移动,而您想要在屏幕上显示的内容也在不断变化.

It is hard to show you the "looks like shit" part, but imagine as you scroll, the contents moves and what you want on screen is continuously shifting.

动态更新高度不起作用,我们有几个选择:在 iOS 上删除视口单元,像 iOS 8 之前一样匹配文档大小,使用小视图大小,使用大视图大小.

Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.

根据我们掌握的数据,使用较大的视图尺寸是最好的折衷方案.大多数使用视口单元的网站大部分时间看起来都很棒.

From the data we had, using the larger view size was the best compromise. Most website using viewport units were looking great most of the time.

Nicolas Hoizey 对此进行了大量研究:https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html

Nicolas Hoizey has researched this quite a bit: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html

没有修复计划

此时,除了避免在移动设备上使用视口高度外,您无能为力.Chrome 在 2016 年也改为了这个:

At this point, there is not much you can do except refrain from using viewport height on mobile devices. Chrome changed to this as well in 2016:

  • https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/BK0oHURgmJ4
  • https://developers.google.com/web/更新/2016/12/url-bar-resize

相关文章