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

我有一个非常奇怪的问题……在每个浏览器和移动版本中,我都遇到了以下问题:

  • 加载页面时,所有浏览器都有一个顶部菜单(例如,显示地址栏),当您开始滚动页面时,该菜单会向上滑动。
  • 有时仅在视口的可见部分计算100vh ,因此当浏览器栏向上滑动时100vh会增加(以像素为单位)
  • 由于尺寸已更改,所有布局都会重新绘制和重新调整
  • 对用户体验的不良影响

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

您可以在以下示例中看到问题:

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


简单的测试代码:

/* 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>

泡芙2020/03/24 16:09:04

您可以尝试将position: fixed; top: 0; bottom: 0;属性赋予容器。

十三飞云2020/03/24 16:09:04

在移动设备上使用vh不能与100vh一起使用,因为它们的设计选择是使用设备的整个高度,不包括任何地址栏等。

如果要查找包含与真实视图高度成比例的div高度的布局,请使用以下纯CSS解决方案:

:root {
  --devHeight: 86vh; //*This value changes
}

.div{
    height: calc(var(--devHeight)*0.10); //change multiplier to suit required height
}

您有两个用于设置视口高度的选项,将--devHeight手动设置为有效的高度(但是您需要为要编码的每种类型的设备输入该值)

要么

使用javascript获取窗口高度,然后在加载和刷新视口时更新--devheight(但是这确实需要使用javascript,并且不是纯CSS解决方案)

一旦获得正确的视图高度,就可以通过简单地更改分配高度的每个div中的乘数,以总视口高度的确切百分比创建多个div。

0.10 =视图高度的10%0.57 =视图高度的57%

希望这可以帮助某人;)

十三2020/03/24 16:09:04

对我来说,这样的把戏很成功:

height: calc(100vh - calc(100vh - 100%))
2020/03/24 16:09:04

因为不会被修复,所以您可以执行以下操作:

# html
<body>
  <div class="content">
    <!-- Your stuff here -->
  </div>
</body>

# css
.content {
  height: 80vh;
}

对我来说,这是比使用JavaScript最快,更纯净的解决方案,而JavaScript无法在许多设备和浏览器上运行。

只要使用vh适合您需求的适当值即可

老丝2020/03/24 16:09:04

以下为我工作:

html { height: 100vh; }

body {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
}

/* this is the container you want to take the visible viewport  */
/* make sure this is top-level in body */
#your-app-container {
  height: 100%;
}

body将可视视口的高度,并#your-app-containerheight: 100%将使该容器采取可见视口的高度。

GO2020/03/24 16:09:04

希望这将是一个UA定义的CSS环境变量,如下所示:https : //github.com/w3c/csswg-drafts/issues/2630#issuecomment-397536046

MandyGil2020/03/24 16:09:04

这是我用于我的React应用程序的一种解决方法。

iPhone 11 Pro和iPhone Pro Max-120像素

iPhone 8-80像素

max-height: calc(100vh - 120px);

这是一个折衷,但相对简单的修复

番长2020/03/24 16:09:04

我刚刚发现我设计的Web应用程序在iPhone和iPad上存在此问题,并且发现了一篇文章,建议使用针对特定Apple设备的媒体查询来解决该问题。

我不知道我是否可以在此处共享该文章中的代码,但是地址是这样的:http : //webdesignerwall.com/tutorials/css-fix-for-ios-vh-unit-bug

引用文章:“使用针对旧版本iPhone和iPad分辨率的媒体查询,使元素高度与设备高度匹配。”

他们仅添加了6个媒体查询来适应全高元素,并且它完全由CSS实施,因此可以正常工作。

待编辑中:我目前无法测试,但我会回来报告结果。

达蒙路易2020/03/24 16:09:04

@nils清楚地解释了这一点。

那接下来呢?

我只是回过头来在CSS中使用相对的“经典” %(百分比)

实现某些事情通常比使用它要付出更多的努力vh,但是至少,您有一个相当稳定的解决方案,该解决方案可以在不同的设备和浏览器上工作,而不会出现奇怪的UI故障。

LEY猿2020/03/24 16:09:04

我想出了一个React组件– 检查您是否使用React或不使用浏览源代码,以便可以使其适应您的环境。

它将全屏div的高度设置为window.innerHeight,然后在调整窗口大小时对其进行更新。

番长猴子2020/03/24 16:09:03

Unfortunately this is intentional…

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. :)

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.

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 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

No fix planned

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:

卡卡西Near2020/03/24 16:09:03

您可以尝试min-height: -webkit-fill-available;使用CSS而不是100vh应该解决