我有一个很奇怪的问题…在每个浏览器和手机版本中,我都遇到了这种行为:
当你加载页面时,所有的浏览器都有一个顶部菜单(例如显示地址栏),当你开始滚动页面时,它会向上滑动。
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>
对于我所创建的许多网站,客户端都会要求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规则仍然存在。
在移动设备上使用vh不适合100vh,因为他们的设计选择使用整个设备的高度,不包括任何地址栏等。
如果你正在寻找一个布局,包括div高度成比例的真实视图高度,我使用以下纯css解决方案:
:root {
--devHeight: 86vh; //*This value changes
}
.div{
height: calc(var(--devHeight)*0.10); //change multiplier to suit required height
}
你有两个选项来设置视口高度,手动设置——devHeight为一个工作的高度(但是你需要为你正在编码的每种类型的设备输入这个值)
or
使用javascript获取窗口高度,然后在加载和刷新视口时更新——devheight(然而这需要使用javascript,不是一个纯css解决方案)
一旦你获得正确的视图高度,你可以创建多个div在总视口高度的确切百分比,只需改变乘数在每个div你分配的高度。
0.10 =视图高度的10%
0.57 =视图高度的57%
希望这可以帮助到一些人;)