必须设置 viewport-fit=cover 才能启用 safe-area-inset-*,否则 env() 返回 0px;padding-bottom 是唯一稳妥的适配方式,@supports 检测最可靠,降级用固定值+覆盖,calc() 单位混合在旧 Safari 失效,constant() 已废弃。

只写 env(safe-area-inset-bottom) 或 env(safe-area-inset-top) 是无效的,必须搭配 viewport-fit=cover 才能拿到真实数值;否则所有值都是 0px,适配完全失效。
viewport-fit=cover 是硬性前提,不是可选项
iOS Safari 只有在 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 完整存在时,才会注入 safe-area-inset-* 环境变量。漏掉 viewport-fit=cover,或只写 initial-scale=1,env(safe-area-inset-bottom) 就永远返回 0px。
- 微信 8.0.22 之前、部分企业微信 WebView、旧版 QQ 浏览器等容器根本不支持
viewport-fit,此时env()直接被忽略 - 某些 Hybrid 容器会强制覆盖
<meta>标签,需用 DevTools 检查渲染后实际生效的content值 -
viewport-fit=auto(默认行为)等价于禁用安全区 API,env()恒为0px
padding-bottom 是唯一稳妥的落点方式
对底部 fixed 元素(如 tabbar),直接设 padding-bottom: env(safe-area-inset-bottom) 在该元素自身上;不要写 margin-bottom,它在脱离文档流的元素上不改变布局高度,反而可能撑大可滚动区域。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
- 给
<html>或<body>加padding-bottom会导致整页下移,顶部状态栏区域可能出空白 - flex 布局中靠
margin-top: auto推下来的底部栏,应把padding-bottom: env(safe-area-inset-bottom)加在父容器上 - 顶部 fixed 导航栏适配用
padding-top: env(safe-area-inset-top),同样不能作用于<body>
@supports 检测比 UA 判断更可靠
@supports (padding-bottom: env(safe-area-inset-bottom)) 是唯一推荐的检测方式。UA 字符串不可靠,iOS 版本号和 WebView 实现差异太大,微信、飞书、钉钉等容器对 viewport-fit 支持程度不一,靠 JS 判断容易漏判或误判。
立即学习“前端免费学习笔记(深入)”;
- 降级方案建议:先写
padding-bottom: 34px(iPhone X–13 竖屏典型值),再用@supports覆盖为env()动态值 -
calc(8px + env(safe-area-inset-bottom))在 Safari 15.4 之前不支持单位混合运算,整条声明会被丢弃 -
constant()已废弃,iOS 11.2 起不再支持,别再用
真正容易被忽略的是:安全区域数值是动态的——iPhone 14 Pro Max 的灵动岛在播放音乐、通话时会扩展高度,env(safe-area-inset-top) 会实时变化;但 CSS 无法监听这个变化,JS 也拿不到事件,只能依赖浏览器自动重绘。这意味着,纯 CSS 方案在动态场景下仍可能短暂错位。

















