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

当你加载页面时,所有的浏览器都有一个顶部菜单(例如显示地址栏),当你开始滚动页面时,它会向上滑动。 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>


当前回答

看看这个答案:https://css-tricks.com/the-trick-to-viewport-units-on-mobile/

// First we get the viewport height and we multiple it by 1% to get a value for a vh unit let vh = window.innerHeight * 0.01; // Then we set the value in the --vh custom property to the root of the document document.documentElement.style.setProperty('--vh', `${vh}px`); // We listen to the resize event window.addEventListener('resize', () => { // We execute the same script as before let vh = window.innerHeight * 0.01; document.documentElement.style.setProperty('--vh', `${vh}px`); }); body { background-color: #333; } .module { height: 100vh; /* Use vh as a fallback for browsers that do not support Custom Properties */ height: calc(var(--vh, 1vh) * 100); margin: 0 auto; max-width: 30%; } .module__item { align-items: center; display: flex; height: 20%; justify-content: center; } .module__item:nth-child(odd) { background-color: #fff; color: #F73859; } .module__item:nth-child(even) { background-color: #F73859; color: #F1D08A; } <div class="module"> <div class="module__item">20%</div> <div class="module__item">40%</div> <div class="module__item">60%</div> <div class="module__item">80%</div> <div class="module__item">100%</div> </div>

其他回答

VH 100在移动设备上表现不佳,因为它没有考虑iOS栏(或其他平台上的类似功能)。

一个很好的解决方案是使用JavaScript的"window.innerHeight"。

简单地将元素的高度赋给这个值。 $ (' .element-name ') .height (window.innerHeight);

注意:在JS中创建一个函数可能很有用,这样当屏幕调整大小时,高度就可以改变。但是,我建议只在屏幕宽度改变时调用该函数,这样当用户向下滚动页面时iOS栏消失时,元素的高度就不会跳跃。

@nils解释得很清楚。

接下来呢?

我只是回到使用相对'经典' %(百分比)在CSS。

实现一些东西通常比使用vh更费力,但至少,你有一个相当稳定的解决方案,它可以跨不同的设备和浏览器工作,没有奇怪的UI故障。

我刚刚发现我设计的一个web应用程序在iphone和ipad上有这个问题,并发现一篇文章建议使用针对特定苹果设备的媒体查询来解决这个问题。

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

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

他们只添加了6个媒体查询来适应全高度元素,它应该可以工作,因为它是完全由CSS实现的。

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

关于这个问题及其可能的解决方案可以在这篇博客文章中找到:在100vh布局中寻址iOS地址栏

我最终在我的React应用程序中的解决方案是利用上面帖子中描述的React -div-100vh库。

问题:

if ( refDOM.clientHeight != window.innerHeight )

解决方案:

refDOM.style.setProperty('--MYvh', window.innerHeight + 'px' ) ;

完成:

const mobileShit = function ( refDOM ) {
    console.log ( `refDOM.clientHeight : ${refDOM.clientHeight}` ) ;
    console.log ( `window.innerHeight : ${window.innerHeight}` ) ;
    if ( refDOM.clientHeight != window.innerHeight ) { // accounting for mobile
        refDOM.style.setProperty('--MYvh', window.innerHeight + 'px' ) ;
    }
} ;

CSS(通过脚本修改,是的,当任何事情发生变化时,你必须处理事件):

:root {
    --MYvh : 100vh ;
}