应使用100dvh替代100vh解决iOS Safari视口高度计算错误问题,但需用@supports包裹并确保viewport标签正确,绝对定位元素需父容器设高度或改用top/bottom: 0。

Flex容器min-height: 100vh在iOS Safari里算错高度
不是你写错了,是Safari把地址栏、底部工具栏的高度硬塞进100vh的计算里。刚加载时它按设备物理屏高(比如iPhone 14的844px)算1vh=8.44px,结果100vh=844px——但你能看见的区域可能只有700px左右。滚动后地址栏收起,视口变大,100vh却死守初始值不动,导致内容被裁切、底部留白、甚至意外滚动条。
-
min-height: 100vh在iOS Safari中初始渲染就偏高,overflow: hidden都压不住 - 用
height: 100vh更危险:内容超长时直接被截断,用户根本拉不到底部 - Android Chrome和新版Edge基本正常;微信WebView行为跟iOS Safari 15.x一致,同样不可靠
该用100dvh,但必须用@supports正确包裹
100dvh(dynamic viewport height)才是正解——它始终反映当前可见视口高度,不受地址栏或键盘弹出干扰。但直接写min-height: 100vh; min-height: 100dvh;是错的:老Safari忽略第二行,新Safari也可能因解析顺序走错分支。
- 正确写法:
.page { min-height: 100vh; } @supports (min-height: 100dvh) { .page { min-height: 100dvh; } } - 别用PostCSS插件自动转换单位,它们常把
100dvh错误降级成100vh -
100dvh需Chrome 105+ / Safari 16.4+支持;低于此版本必须JS降级
绝对定位元素设了100dvh还是没撑开
因为position: absolute元素的百分比高度(包括100dvh)依赖包含块(containing block)的高度。如果父容器没设高度,100dvh实际计算为0——常见于弹窗、遮罩层、底部固定按钮。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
- 检查父容器(如
body或.wrapper)是否写了min-height: 100dvh或显式高度 - 别对绝对定位元素裸写
height: 100dvh,改用top: 0; bottom: 0;更稳定 - 若父容器本身靠
--vh变量驱动,确保它先完成初始化,否则子元素读到的是初始1px
旧版Safari(iOS 9–12)flex: 1子项高度坍缩
旧WebKit把flex: 1错误解析为flex-basis: auto,再叠加默认min-height: auto,结果子项按内容撑开而非拉伸填满。DevTools里看到的computed flex-basis是auto,不是0px。
立即学习“前端免费学习笔记(深入)”;
- 所有参与分配的子元素必须同时加
flex-basis: 0px和min-height: 0 - 不能写
flex-basis: 0%——Safari会直接忽略 - 子项含
<img>时,额外加height: auto,否则Safari可能冻结其内在尺寸估算 - 嵌套Flex容器(如卡片内再套
display: flex; flex-direction: column)时,每一层都要重复这套组合
<meta name="viewport" content="width=device-width, initial-scale=1.0">缺失或用了maximum-scale=1,100dvh会退化为不可靠行为,页面整体缩小、右侧滑出空白、document.documentElement.clientWidth远小于屏幕宽度。

















