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

我有一个很奇怪的问题......在每一个浏览器和移动版本中,我遇到过这种情况:

  • 当你开始滚动页面时,所有浏览器都有一个顶部菜单,当你加载页面时(例如显示地址栏),这些页面会向上滑动。
  • 100vh仅在视口的可见部分进行计算,因此当浏览器栏向上滑动100vh时(以像素为单位)
  • 自尺寸发生变化后,所有布局都重新涂漆并重新调整
  • 用户体验不好的跳跃效果
  • 怎么能避免这个问题? 当我第一次听到视口高度时,我很兴奋,我想我可以使用它固定高度块istead使用JavaScript,但现在我认为唯一的方法来做到这一点实际上是JavaScript的一些resize事件...

    你可以在示例站点看到问题

    任何人都可以帮我/建议一个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 sould 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移动中),这是故意的,因为它可以防止其他问题。 Benjamin Poulain回复了一个webkit bug:

    这完全是故意的。 为了达到这个效果,我们做了很多工作。 :)

    基本问题是:可见区域在您滚动时动态变化。 如果我们相应地更新CSS视口高度,则需要在滚动过程中更新布局。 不仅这看起来像狗屎,而且在大多数页面中以60 FPS的速度进行操作实际上是不可能的(60 FPS是iOS上的基准帧速率)。

    很难向您展示“看起来像狗屎”的部分,但想象一下,当您滚动时,内容会移动,屏幕上您想要的内容会不断移动。

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

    从我们的数据来看,使用较大的视图尺寸是最好的折衷方案。 大多数使用视口单元的网站大部分时间都很漂亮。

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

    没有修复计划

    此时,除了避免在移动设备上使用视口高度外,您可以做的不多。 移动Chrome浏览器似乎也想调整这一点,虽然不知道他们是否会继续。


    对于我建立的许多网站来说,客户端会要求100vh的横幅广告,正如您找到的那样,当您开始滚动时,它会在移动设备上造成糟糕的“跳动”体验。 这就是我解决问题的方法,以便在所有设备上实现顺畅的一致体验:

    我首先将我的横幅元素CSS设置为height:100vh

    然后我使用jQuery来获取横幅元素的像素高度,并使用此高度应用内联样式。

    var viewportHeight = $('.banner').outerHeight();
    $('.banner').css({ height: viewportHeight });
    

    这样做可以解决移动设备上的问题,因为页面加载时,横幅元素使用CSS设置为100vh,然后jQuery通过将内联CSS放置在横幅元素上,从而在用户开始滚动时停止调整大小,从而覆盖此元素。

    但是,在桌面上,如果用户调整浏览器窗口大小,我的banner元素将不会调整大小,因为由于上述jQuery,它现在具有固定的像素高度。 为了解决这个问题,我使用Mobile Detect将“移动”类添加到文档的正文中。 然后我在if语句中包装上面的jQuery:

    if ($('body').hasClass('mobile')) {
      var viewportHeight = $('.banner').outerHeight();
      $('.banner').css({ height: viewportHeight });
    }
    

    因此,如果用户在移动设备上,我的页面主体上会出现'mobile'类,并执行上面的jQuery。 因此,我的横幅元素只会在桌面上获得移动设备上应用的内嵌CSS,而原始的100vh CSS规则仍然适用。


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

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

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

    他们只添加了6个媒体查询以适应全高度元素,并且它应该在完全采用CSS的情况下工作。

    编辑暂挂:我现在无法测试,但我会回来报告我的结果。

    链接地址: http://www.djcxy.com/p/15497.html

    上一篇: CSS3 100vh not constant in mobile browser

    下一篇: What are the advantages of DIVS over tables?