必须同时满足viewport-fit=cover、@supports(padding-top:env(safe-area-inset-top))检测、带单位fallback三者,缺一不可;否则env()值为0px或整条规则被丢弃。

iPhone 刘海屏顶部内容被遮挡,核心不是“怎么加 safe-area-inset-top”,而是**必须让这个值真正生效**。它不会自动起作用,需要三个条件同时满足:viewport-fit=cover、@supports 正确检测、带单位 fallback。
必须加 viewport-fit=cover
这是硬性前提,缺一个字都不行。在 <head> 中写入完整 meta:
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
注意:
- initial-scale=1.0 不能省,iOS Safari 只在此条件下注入安全区域变量
- 微信 WebView、PWA 框架等可能动态重写该 meta,真机调试时务必检查 document.querySelector('meta[name=viewport]').content
- Android Chrome(非 WebView)基本不支持,env() 值始终为 unset 或 0px
@supports 必须写对语法
错误写法会直接跳过整块样式,导致 fallback 失效:
- ❌
@supports (env(safe-area-inset-top)) { ... }—— 语法非法,整块被忽略 - ❌
@supports (safe-area-inset-top: 44px) { ... }—— 不是 CSS 属性,检测无效 - ✅
@supports (padding-top: env(safe-area-inset-top)) { ... }—— 唯一合法写法,浏览器检测该声明能否执行
推荐把检测和应用合并,例如:
@supports (padding-top: env(safe-area-inset-top)) {
.header { padding-top: env(safe-area-inset-top); }
}
适配 fixed 定位的顶部栏
如果头部是 position: fixed; top: 0,别用 padding-top——它对脱离文档流的元素无效。
正确做法是控制定位偏移:
-
top: env(safe-area-inset-top, 0px);(单位 不能省) - 或更现代写法:
inset: env(safe-area-inset-top, 0px) auto auto auto; - 建议加层叠 fallback:
top: 0; top: env(safe-area-inset-top, 0px);
这样 Safari 在识别 env() 时会覆盖前面的 top: 0,不支持时则回退到原始位置。
全局变量统一管理(可选但推荐)
在 :root 中定义 CSS 自定义变量,便于复用和维护:
:root {
--safe-top: env(safe-area-inset-top, 0px);
--safe-bottom: env(safe-area-inset-bottom, 0px);
}
然后在组件中使用:padding-top: var(--safe-top); 或 top: var(--safe-top);
注意:仍需配合 @supports 检测,否则 var() 的 fallback 不会触发 env() 的兼容逻辑。


















