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

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


当前回答

不要使用推荐的方法,如-webkit-fill-available。 我花了一整天的时间来修复这个“bug”。

当你的应用程序被一个带有“下巴”的浏览器加载时,添加一个类。

JavaScript

// Angular example but applicable for any JS solution
@HostBinding('class.browser-has-chin') browserHasChin: boolean = false;

public ngOnInit(): void {
    this.browserHasChin = this._isMobileSafari();
}

private _isMobileSafari() {
    return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/) ? true : false;
}

CSS

.browser-has-chin {
  @media screen and (max-device-width: 767px){
    // offset with padding or something
  }
}

注: 在跨浏览器兼容性方面,-webkit-fill-available道具存在一些重大问题。

我能够让它在Chrome和iOS Safari中工作,以修复下巴/高度计算问题。然而,它破坏了Android Chrome和Firefox也有bug。

似乎-webkit-fill-available在某种程度上是匆忙加入webkit的,也许是苹果偶然采用的,作为下巴/高度计算的修复?

它依赖于内在的大小,这是不安全的使用。

其他回答

在我的应用程序,我这样做(typescript和嵌套postcss,所以改变相应的代码):

const appHeight = () => {
    const doc = document.documentElement
    doc.style.setProperty('--app-height', `${window.innerHeight}px`)
}
window.addEventListener('resize', appHeight)
appHeight()

在你的css中:

:root {
    --app-height: 100%;
}

html,
body {
    padding: 0;
    margin: 0;
    overflow: hidden;
    width: 100vw;
    height: 100vh;

    @media not all and (hover:hover) {
        height: var(--app-height);
    }
}

它至少可以在chrome手机和ipad上运行。不工作的是,当你添加你的应用程序到iOS的主屏幕上,并改变方向几次-以某种方式缩放级别混乱的innerHeight值,我可能会发布一个更新,如果我找到一个解决方案。

Demo

你可以试试min-height: -webkit-fill-available;而不是100vh。应该得到解决

@nils解释得很清楚。

接下来呢?

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

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

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

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

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

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

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

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

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

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