我有一个很奇怪的问题…在每个浏览器和手机版本中,我都遇到了这种行为:

当你加载页面时,所有的浏览器都有一个顶部菜单(例如显示地址栏),当你开始滚动页面时,它会向上滑动。 100vh有时只在视口的可见部分计算,所以当浏览器栏向上滑动时,100vh增加(以像素计算)。 所有布局重新油漆和重新调整,因为尺寸已经改变 对用户体验有不好的跳跃效果

如何避免这个问题?当我第一次听说viewport-height时,我很兴奋,我认为我可以使用它来固定高度块,而不是使用javascript,但现在我认为唯一的方法实际上是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>


当前回答

对于我所创建的许多网站,客户端都会要求100vh的横幅,正如你所发现的那样,当你开始滚动时,它会导致糟糕的“跳跃”体验。这就是我如何在所有设备上获得流畅一致的体验:

我首先设置我的横幅元素CSS的高度:100vh

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

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

这样做解决了移动设备上的问题,当页面加载时,使用CSS将横幅元素设置为100vh,然后jQuery通过在我的横幅元素上放置内联CSS来阻止它在用户开始滚动时调整大小。

然而,在桌面上,如果用户调整他们的浏览器窗口大小,我的横幅元素不会调整大小,因为它现在有一个固定的高度像素设置由于上述jQuery。为了解决这个问题,我使用Mobile Detect在我的文档正文中添加了一个“Mobile”类。然后我将上面的jQuery封装在if语句中:

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

因此,如果用户在移动设备上,“mobile”类就会出现在我的页面主体上,并且会执行上面的jQuery。所以我的横幅元素只会得到内联CSS应用在移动设备上,同时在桌面上,原来的100vh CSS规则仍然存在。

其他回答

body {
   width: 100%;
   height: 100%
}

100%会根据屏幕大小自行调整但出于某种原因 100vh在屏幕变化时调整有问题,所以如果你使用100vh或100%,使用底部0将受到影响

例如,当搜索栏在视图中或不在移动中,100%与变化,其中100vh将粘在屏幕高度的第一个值

React用useEffect和useState挂钩解决方案

    function App() {
      const [vh, setVh] = useState(window.innerHeight);
    
      useEffect(() => {
        const updateVh = () => {
          setVh(window.innerHeight);
        };
    
        window.addEventListener('resize', updateVh);
    
        return () => window.removeEventListener('resize', updateVh);
      }, []);
    
      return (
        <div style={{ height: vh }}>
          {vh} px
        </div>
      );
}

演示:https://jsfiddle.net/poooow/k570nfd9/

在我的例子中,我有一些元素设置为90vh,另一个元素设置为70px 将70px改为10vh解决了它

不要把vh和px混合

下面的方法对我很有效:

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-container with height: 100%将使容器采用可见视口高度。

不幸的是,这个问题至今仍然存在。最大的误导是不可能用浏览器的设备工具栏来表示情况。

我刚刚解决了这个问题(在PC、iOS和android浏览器上进行了测试):

.your_class {
   height: 100vh,
   max-height: 100%, // <-- add the line
   ...some other props,
}

我希望它能节省你的时间。