min-height: 100vh 常失败源于三层干扰:浏览器默认样式、父容器高度传递断层、移动端视口动态变化;需配合清 margin/padding、设 html/body 高度、box-sizing:border-box 及正确 flex 配置,并在移动端用 @supports 降级至 100dvh 或 js 动态同步 window.innerheight。

直接用 min-height: 100vh 实现全屏高度,90% 的失败不是因为写错了,而是没处理好三层干扰:浏览器默认样式、父容器高度传递断层、移动端视口动态变化。它能保底,但不能当“全屏”唯一解。
为什么 min-height: 100vh 常常撑不满或留白
它只保证“至少一屏高”,不控制“是否贴顶贴底”,更不响应地址栏/键盘变化。常见现象包括:
- iOS Safari 滚动时地址栏收起,
100vh还按旧高度算,底部突然露白 -
body有默认margin: 8px,实际可用高度 =100vh - 16px - 父容器没设
height或min-height,子元素的100vh计算基准错乱 - 用了
padding或border但没配box-sizing: border-box,内容溢出触发滚动条
min-height: 100vh 必须搭配的基础样式
单独一行 min-height: 100vh 几乎必出问题。以下四点缺一不可:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
html, body { margin: 0; padding: 0; }—— 清掉默认边距,否则高度被吃掉 -
html, body { height: 100%; }或min-height: 100vh—— 确保根级有高度可继承 -
* { box-sizing: border-box; }—— 避免padding/border溢出 - 若需 Flex 居中,父容器必须同时有
display: flex+min-height: 100vh,仅子元素设flex无效
移动端必须换 100dvh,但不能直接替换
100dvh 是 iOS Safari 16.4+、Chrome 105+ 等支持的动态视口单位,能响应地址栏和键盘显隐。但它不能写成 height: 100dvh,否则超长内容会被裁剪:
- 正确写法是:
min-height: 100vh;后紧跟@supports (min-height: 100dvh) { .fullscreen { min-height: 100dvh; } } - 别用
@supports (height: 100dvh)—— Safari 16.3 会识别该语句但不支持dvh,导致降级失效 - 微信内置浏览器、iOS 15.x 及更早版本完全忽略
dvh,此时必须靠 JS 补偿
JS 动态同步 window.innerHeight 的关键时机
即使写了 min-height: 100dvh,首次加载或键盘弹出时仍可能滞后。真正稳的 JS 方式不是监听 resize,而是:
- 监听
resize+focusin+focusout—— 键盘弹出/收起会改window.innerHeight,但不一定触发resize - 节流执行,推荐用
requestAnimationFrame包一层,避免高频重绘 - 不要在
DOMContentLoaded里直接设高 —— 此时window.innerHeight可能还是初始快照值,未反映地址栏真实状态 - 若页面有固定 header/footer,全屏区块高度应为
window.innerHeight - headerHeight - footerHeight,不能硬写100vh
真正难的不是写对那一行 CSS,而是判断当前环境是否需要 fallback、是否要加 JS、以及哪一层样式正在悄悄吃掉那几像素高度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










