100dvh能解决地址栏遮挡而100vh不行,因100vh基于固定布局视口(含地址栏),导致加载时偏高留白、滚动后冻结不变引发截断;100dvh是动态单位,实时响应地址栏显隐和键盘弹起,iOS 16.4+/Chrome 105+原生支持,需用min-height并配合@supports降级确保兼容。

为什么100dvh能解决地址栏遮挡,而100vh不行
100vh基于「布局视口」计算,把地址栏、底部导航栏这些可隐藏区域全算进去了;页面刚加载时地址栏展开,它偏高,导致底部留白;滚动后地址栏收起,100vh的值却冻结不动,实际可视区变大,但容器没重算——底栏就被内容顶上去或截断。100dvh是动态单位,始终反映此刻真实可见高度,地址栏收/展、软键盘弹起都会触发重算,iOS 16.4+ 和 Chrome 105+ 已原生支持。
必须用min-height: 100dvh,不能直接写height
直接写height: 100dvh在内容不足时会强制撑满,导致底部元素上浮、flex居中失效;而min-height: 100dvh只保证“至少”撑到当前可视高度,内容多时自然延伸,更符合实际需求。但注意:min-height本身不触发重排,所以必须搭配父容器display: flex或display: grid才能让子元素正确响应高度变化。
@supports检测不是可选,是必须加的降级逻辑
不加@supports,iOS 15、微信 WebView(基于旧版 Safari 内核)、部分安卓 WebView 会直接忽略100dvh,且不 fallback 到100vh,导致容器塌陷为min-height: 0。正确写法是:
.page {
min-height: 100vh;
@supports (min-height: 100dvh) {
min-height: 100dvh;
}
}
这个顺序不能反——CSS 层叠规则要求降级值写在前面,新值用@supports包裹在后,否则老浏览器连100vh都拿不到。
立即学习“前端免费学习笔记(深入)”;
flex布局里用100dvh,还得防子项min-height: auto吃掉空间
当父容器设了min-height: 100dvh并用display: flex; flex-direction: column,底部吸底靠margin-top: auto或align-self: flex-end时,如果某个子项(比如主内容区)默认min-height: auto,它可能把剩余空间全占掉,导致底栏被挤出可视区。要显式控制:
- 给主内容区加
min-height: 0(防止它撑满) - 确保底栏是普通块级元素,不是
position: fixed - 避免对底栏设
height以外的弹性约束(如flex: 0 0 48px比flex: 1更稳)


















