必须添加viewport-fit=cover,否则env(safe-area-inset-bottom)无效;正确写法是padding-bottom: env(safe-area-inset-bottom, 0px),作用于fixed/absolute底部容器,fallback单位不可省略。

viewport-fit=cover 没写,env(safe-area-inset-bottom) 就是摆设
不加 viewport-fit=cover,iOS 和部分安卓 WebView 根本不会注入 safe-area-inset-bottom 环境变量,env(safe-area-inset-bottom) 会返回 0px 或空值,CSS 直接失效。
必须确保 <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> 完整存在,且没被脚本覆盖。微信 8.0.22 之前版本、某些企业微信 WebView 会强制重写 <meta>,得用开发者工具检查渲染后的实际 HTML。
- 漏写
width=device-width或initial-scale=1可能导致viewport-fit=cover不生效 - 多个 UI 库(如 vant、nutui)可能自动注入自己的
<meta>,覆盖你写的 - iframe 子页无法继承父页的
viewport-fit设置,子页必须自己声明
padding-bottom 是唯一推荐的写法,别碰 margin-bottom 和 bottom
margin-bottom: env(safe-area-inset-bottom) 在 position: fixed 元素上无效;在 flex 布局中还会破坏高度计算,导致内容被“挤出”可视区。
bottom: env(safe-area-inset-bottom) 更危险:它只是把元素下推,但容器高度不变,按钮反而悬在黑条上方,离可点区域更远。
- 正确做法是直接对底部容器自身设
padding-bottom: env(safe-area-inset-bottom, 0px) - 该容器应是
position: fixed或position: absolute,不能作用于或 - 如果是 flex 布局靠
margin-top: auto推下来的底部栏,padding-bottom要加在父容器上
fallback 值必须显式带单位,且顺序不能错
env() 的 fallback 值不能省略单位,env(safe-area-inset-bottom, 0) 是无效的,必须写成 env(safe-area-inset-bottom, 0px)。
如果要兼容老设备(比如 iOS 11.2 以下),constant() 已废弃,别再用;现代项目只保留 env() 即可(2026 年绝大多数 iOS 设备已升级)。
- 降级样式必须写在
env()之前:padding-bottom: 34px; padding-bottom: env(safe-area-inset-bottom, 0px); - 用
max(16px, env(safe-area-inset-bottom))可防极端情况(如 iPad mini 返回0px) -
calc(8px + env(safe-area-inset-bottom))需 Safari 15.4+,低版本会整条丢弃,慎用
env(safe-area-inset-bottom) 不等于“永远有值”
这个变量在横屏、旧机型、非 Safari 浏览器(如 Android Chrome)、甚至某些三星 One UI 版本上都可能返回 0px。不能假设它一定生效。
打开 Safari 开发者工具 → Elements → 计算样式,搜索 env(safe-area-inset-bottom),看是否真有值(比如 34px)。没值就说明当前环境不支持,得靠 UA 判断或 JS 注入降级 class。
-
env(safe-area-inset-left)和env(safe-area-inset-right)在绝大多数设备上都是0px,基本不用管 -
env(safe-area-inset-top)虽然常用,但要注意它包含状态栏高度,和100vh混用会导致双倍留白 - 不要在
height: 100vh容器上只靠padding适配,内容会被下推两次
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











