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

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


当前回答

我们有新的视口单元lvh, svh和dvh来拯救。这在最新的谷歌I/O 2022网络作品视频中得到了证明。

您可能希望继续使用dvh,以便浏览器在滚动时适应移动设备的隐藏选项卡。它的工作方式类似于宽度dvw, lvw和svw单位。

这是视频中的一个简洁的插图:https://youtu.be/Xy9ZXRRgpLk?t=982

我能用吗?

这是目前工作在我的Chrome金丝雀与标志“实验功能”启用。

其他回答

我在下面创建了两个例子:

要展示如何高度:100vh的高度可以导致滚动在移动chrome浏览器:

代码:https://codesandbox.io/embed/mobile-viewport-100vh-issue-nxx8z?fontsize=14&hidenavigation=1&theme=dark

演示:https://nxx8z.csb.app/


解决方案使用位置:固定解决问题和纯CSS:

代码:https://codesandbox.io/s/mobile-viewport-100vh-issue-fix-forked-ypx5x?file=/index.html

演示:https://ypx5x.csb.app/

我们有新的视口单元lvh, svh和dvh来拯救。这在最新的谷歌I/O 2022网络作品视频中得到了证明。

您可能希望继续使用dvh,以便浏览器在滚动时适应移动设备的隐藏选项卡。它的工作方式类似于宽度dvw, lvw和svw单位。

这是视频中的一个简洁的插图:https://youtu.be/Xy9ZXRRgpLk?t=982

我能用吗?

这是目前工作在我的Chrome金丝雀与标志“实验功能”启用。

您可以通过添加以下脚本和样式来做到这一点

function appHeight() {
  const doc = document.documentElement
  doc.style.setProperty('--vh', (window.innerHeight*.01) + 'px');
}

window.addEventListener('resize', appHeight);
appHeight();

风格

.module {
  height: 100vh; /* Fallback for browsers that do not support Custom Properties */
  height: calc(var(--vh, 1vh) * 100);
}

因为它不会被修复,你可以这样做:

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

# css
.content {
  height: 80vh;
}

对我来说,这是比JavaScript更快、更纯粹的解决方案,因为JavaScript无法在许多设备和浏览器上运行。

只要使用合适的vh值就可以了。

在我的应用程序,我这样做(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