应使用min-h-[100dvh]替代h-screen或min-h-screen,并配合flex flex-col布局,因dvh能动态响应软键盘弹出和地址栏变化,而vh在iOS Safari等环境中静态冻结导致内容截断或留白。

直接换掉 h-screen,它在 iOS Safari 和部分 Android WebView 里根本不可靠——键盘弹出、地址栏收放都会让 100vh “冻住”在初始值上,导致内容被截或底部留白。
为什么 h-screen 和 min-h-screen 都会失效
它们都编译成 height: 100vh 或 min-height: 100vh,而 vh 是静态单位:
- iOS Safari(尤其 16.3 及更早)在软键盘弹出后不更新
vh值,仍按未弹键盘时的视口算 - 华为、UC 等 WebView 直接忽略
vh,整条样式失效 -
min-h-screen虽比h-screen容错稍好,但一旦父容器没设flex或高度上下文,flex-1就没空间可分,主内容照样塌成一条线
正确写法:min-h-[100dvh] + flex 布局
dvh(dynamic viewport height)才是真·响应式单位,iOS 16.4+、Chrome 109+ 已稳定支持,Tailwind ≥ 3.3 可直接用:
- 必须搭配
flex flex-col,否则min-h-[100dvh]只设最小高度,子项不会自动弹性分配空间 - 结构示例:
<div class="min-h-[100dvh] flex flex-col"> <header class="h-16"></header> <main class="flex-1 overflow-y-auto"></main> <footer class="h-12"></footer> </div>
- 别混用
h-full和h-screen:h-full依赖父高,h-screen依赖视口,逻辑冲突
移动端侧边栏滚动异常?不是高度问题,是占位没清干净
常见现象:抽屉式侧边栏一打开,整个页面就多出垂直滚动条——这不是侧边栏本身高度不够,而是它仍参与文档流:
立即学习“前端免费学习笔记(深入)”;
- 错误结构:
<div class="hidden"><div class="fixed inset-0"></div></div>—— 外层div是static,可能带min-h-screen,浏览器计算body高度时把它算进去了 - 正确做法:把
fixed直接加在最外层容器上,例如<div id="mobile-menu" class="fixed z-50 hidden inset-y-0 left-0 w-full"> - 内容区要内部滚动?别用
h-full,改用max-h-[calc(100vh-4rem)] overflow-y-auto(预留顶部导航高度)
真正麻烦的不是换单位,而是所有依赖高度的布局都要同步改:flex 子项是否被拉伸、overflow 是否触发 BFC、fixed 元素是否彻底脱离文档流——漏掉任意一环,100dvh 也救不回来。


















