必须加 viewport-fit=cover,否则 env(safe-area-inset-bottom) 永远是 0px;正确写法是;padding-bottom 是唯一稳妥的落点方式;兼容性需用 @supports 检测。

必须加 viewport-fit=cover,否则 env(safe-area-inset-bottom) 永远是 0px
很多开发者写了 padding-bottom: env(safe-area-inset-bottom) 却没效果,根本原因不是 CSS 写错,而是 HTML 的 <meta name="viewport"> 缺了 viewport-fit=cover。iOS Safari 只有在该属性完整存在时,才会注入 safe-area-inset-* 环境变量;缺了它,env() 就恒为 0px,适配完全失效。
正确写法是:
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
注意:viewport-fit=auto(默认值)等价于禁用安全区 API;某些 Hybrid 容器(如旧版企业微信、QQ 浏览器)会强制覆盖这个 <meta>,务必用 DevTools 查看渲染后实际生效的 content 值。
padding-bottom 是唯一稳妥的落点方式,别用 margin-bottom 或 bottom
对 position: fixed 的底部 Tab 栏,直接设 bottom: env(safe-area-inset-bottom) 是无效的——它只是把元素往下推,但不改变布局高度,仍可能被 Home Indicator 截断。而 margin-bottom 在脱离文档流的元素上不参与高度计算,反而可能撑大可滚动区域。
立即学习“前端免费学习笔记(深入)”;
正确做法是把留白加在「容器内部」:
- Tab 栏自身是
fixed:给它加padding-bottom: env(safe-area-inset-bottom) - Tab 栏靠
flex+margin-top: auto推下来:把padding-bottom: env(safe-area-inset-bottom)加在父容器上 - 顶部
fixed导航栏:用padding-top: env(safe-area-inset-top),且不能作用于(会被重置)
兼容性 fallback 必须用 @supports 检测,不是 UA 判断
微信 8.0.22 之前、部分企业微信 WebView、旧版 QQ 浏览器等根本不支持 viewport-fit,此时 env() 直接被忽略,不会报错也不会降级。
推荐写法是:
@supports (padding-bottom: env(safe-area-inset-bottom)) {<br> .tab-bar {<br> padding-bottom: env(safe-area-inset-bottom);<br> }<br>}
这样既避开旧容器的解析异常,又比 JS 判断 UA 或硬写 34px 更可靠。不要用 constant(safe-area-inset-bottom) —— 它是 iOS
安卓和旧 iOS 会忽略 env(),但降级必须自然,不能多出空白
单纯写 padding-bottom: 0; padding-bottom: env(safe-area-inset-bottom); 就够了:CSS 层叠机制会让不支持的浏览器用第一个声明,支持的用第二个,无副作用。
如果需要叠加固定值(比如 Tab 栏本身有 20px 内边距),要用 calc(),但注意:
-
calc(20px + env(safe-area-inset-bottom))在旧版 Safari( - 小程序里常用
rpx,写成calc(20rpx + env(safe-area-inset-bottom))更稳妥 - 绝对不要全局给
加padding-bottom,会导致整页下移,顶部状态栏区域可能出现空白
最易被忽略的一点:安全区留白必须加在“视觉容器”上,而不是靠 JS 动态测 window.innerHeight —— 这个值永远不含安全区偏移,不可靠。真机测试时,一定要关掉 Safari 的「请求桌面站点」,否则安全区变量不会注入。


















