我有一个很奇怪的问题…在每个浏览器和手机版本中,我都遇到了这种行为:
当你加载页面时,所有的浏览器都有一个顶部菜单(例如显示地址栏),当你开始滚动页面时,它会向上滑动。
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>
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/
在移动设备上使用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%
希望这可以帮助到一些人;)
我刚刚发现我设计的一个web应用程序在iphone和ipad上有这个问题,并发现一篇文章建议使用针对特定苹果设备的媒体查询来解决这个问题。
我不知道是否可以在这里分享那篇文章中的代码,但是地址是:http://webdesignerwall.com/tutorials/css-fix-for-ios-vh-unit-bug
引用这篇文章:“使用针对旧版本iPhone和iPad分辨率的媒体查询,将元素高度与设备高度匹配。”
他们只添加了6个媒体查询来适应全高度元素,它应该可以工作,因为它是完全由CSS实现的。
编辑等待:我现在无法测试它,但我会回来报告我的结果。
我在下面创建了两个例子:
要展示如何高度: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金丝雀与标志“实验功能”启用。