必须添加 viewport-fit=cover 才能使 env(safe-area-inset-bottom) 在 ios safari 真机生效,否则返回 0px;css 中需用 padding-bottom: env() 配合 fallback 值,并推荐使用 tailwindcss-safe-area 插件统一管理。

必须同时加 viewport-fit=cover 和 env(safe-area-inset-bottom),否则真机上永远返回 0px;仅写 CSS 里的 env() 没用,iOS Safari 不注入变量。
viewport-fit=cover 是硬性前提,不是可选项
没有它,env(safe-area-inset-*) 在 iOS Safari 中一律返回 0px,DevTools 模拟可能正常,但真机完全无反应。常见错误是只写了 width=device-width, initial-scale=1.0,漏掉 viewport-fit=cover。
正确写法:<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
- 必须放在
中,且不能被框架(如 Next.js)自动生成的viewport覆盖(比如带user-scalable=no的版本) - 微信、QQ 等旧 WebView 基本不支持
viewport-fit,此时env()直接被忽略,无法 fallback - 可用
@supports (padding-bottom: env(safe-area-inset-bottom))检测支持性,比 UA 判断更可靠
padding-bottom: env() 比 margin-bottom: env() 更稳妥
对 position: fixed; bottom: 0 的底部导航栏,优先用 padding-bottom,而非 margin-bottom 或 bottom: calc()。
-
padding-bottom是“撑开”内容区域,符合留出可点击空间的设计意图 -
margin-bottom容易在 flex / absolute 场景下破坏布局流,甚至引入额外滚动高度 - 不要写
bottom: calc(8px + env(safe-area-inset-bottom))—— Safari 15.4 之前不支持单位混合运算,整条声明会被丢弃 - 安全写法:先设
padding-bottom: 20px(fallback),再覆盖为padding-bottom: env(safe-area-inset-bottom)
用 tailwindcss-safe-area 插件省去手写逻辑
手动维护 padding-bottom: 20px; padding-bottom: env(safe-area-inset-bottom) 容易漏、难复用,tailwindcss-safe-area 提供语义化类名,自动处理 fallback 和多端兼容。
- 安装后在
tailwind.config.js中启用插件,无需改 HTML 结构 -
pb-safe→padding-bottom: 20px; padding-bottom: env(safe-area-inset-bottom) -
pb-safe-or-8→padding-bottom: max(8px, env(safe-area-inset-bottom)),适合既要最小留白又要适配安全区的场景 - 该插件不生成静态值,而是动态映射
env(),避免 PostCSS 插件(如postcss-env-function)提前转成固定像素导致失效
最常被忽略的是 viewport-fit=cover 缺失和类名 fallback 顺序写反——前者让 env() 彻底失效,后者让降级样式被覆盖,两者叠加,真机上就只剩一片空白底部。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











