必须加 viewport-fit=cover,否则 env(safe-area-inset-top) 在iOS真机上恒为0;该变量仅在 viewport-fit=cover 模式下启用,需显式声明于meta标签中,并配合@supports检测和max()兜底使用。

必须加 viewport-fit=cover,否则 env(safe-area-inset-top) 永远是 0。
为什么 env(safe-area-inset-top) 不生效
真机上值为 0,不是代码写错了,而是浏览器根本没启用安全区域计算。iOS 的 env() 变量只在 viewport-fit=cover 模式下注入,其他取值(如 auto 或不设)会强制页面退回到“传统安全框”,此时系统不暴露任何 inset 值。
常见错误:<meta name="viewport" content="width=device-width, initial-scale=1"> —— 缺少 viewport-fit=cover,整个适配链就断了。
- 必须显式声明:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> - 不能靠 UA 判断是否加——微信内置浏览器、PWA、WKWebView 在 iOS 上行为一致,都依赖这个 meta
- Android Chrome 和大部分安卓 WebView 完全忽略
viewport-fit,但加了也无害;鸿蒙 ArkWeb 从 4.0+ 开始支持
padding-top 还是 margin-top?用在哪一层
别直接套在 上。全局 padding 会导致非刘海设备(如 iPhone 8)顶部多出空白,且干扰 flex/grid 布局流。
立即学习“前端免费学习笔记(深入)”;
正确做法:只作用于真正需要避让的容器,比如导航栏、标题栏或固定定位的 header。
- 如果 header 是
position: fixed; top: 0,用top: env(safe-area-inset-top)替代top: 0 - 如果 header 是普通流式元素,用
padding-top: env(safe-area-inset-top) - 必须加兜底:
padding-top: max(0px, env(safe-area-inset-top))——max()能让不支持env()的浏览器解析为0px,而padding-top: env(safe-area-inset-top, 20px)是非法语法,整条声明会被丢弃
@supports 检测比 JS 更可靠
不要用 navigator.userAgent 判断 iOS 版本,也不要用 webkit 前缀检测。iOS 15+ 已移除部分前缀依赖,微信、飞书、钉钉等壳内 WebView 行为与 Safari 不完全一致。
唯一可信赖的方式是 CSS 特性检测:
@supports (padding-top: env(safe-area-inset-top)) {
.header-fixed {
top: env(safe-area-inset-top);
top: max(0px, env(safe-area-inset-top));
}
}
注意:@supports 必须包裹所有含 env() 的声明,否则老浏览器遇到不认识的函数会跳过整块规则。
- 不支持
env()的 Android、旧版 iOS 会直接忽略该规则块,走默认样式 - 不能把
@supports和媒体查询混用——@supports (padding-top: env(...)) and (max-width: 768px)在部分安卓 WebView 中解析失败 - 兜底值必须写在
env()后面,顺序不能反,否则无效
iOS 11.0+ 才有 env(),但 constant() 已淘汰
constant(safe-area-inset-top) 是 iOS 11.0 beta 时期的临时方案,iOS 11.2+ 已废弃。现在所有主流 iOS 设备(iPhone X 及以后)只认 env()。
仍看到网上教程写 padding-top: constant(...); padding-top: env(...) 并强调“顺序不能换”,那是过时做法。当前只需保留 env() + max() 兜底即可。
- iOS 11.0–11.1 极少被覆盖,无需兼容;2026 年绝大多数用户已升到 iOS 16+,
env()稳定可用 -
constant()在 iOS 12+ 完全失效,继续写只会增加 CSS 体积和维护成本 - 鸿蒙 ArkWeb 4.0+、三星 Internet 19+ 也只支持
env(),不支持constant()
最易被忽略的一点:安全区域值在横屏时会动态变化,env(safe-area-inset-top) 可能变成 0,而 env(safe-area-inset-left) 出现非零值。如果你的 header 支持横屏,得同时处理左右 inset,不能只盯 top。


















