env(safe-area-inset-bottom) 和 env(safe-area-inset-top) 仅在 viewport-fit=cover、@supports 语法正确、webkit 内核(ios safari/chrome)三者同时满足时才返回真实像素值,缺一不可。

env(safe-area-inset-bottom) 和 env(safe-area-inset-top) 不是“写了就能用”的 CSS 值,它们只在满足三个硬性条件时才返回真实像素值:viewport-fit=cover 必须存在、@supports 检测语法必须正确、且仅限 WebKit 内核(iOS Safari / iOS Chrome)。
viewport-fit=cover 是前提,缺一个字都不行
没这句 meta,所有 env(safe-area-inset-*) 都恒为 0px——不是“不生效”,是系统压根没注入数值。
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">必须完整写在里,initial-scale=1.0不能省,否则 iOS Safari 不启用env() - 常见踩坑:PWA 或 uni-app 的 JS 动态重写了
<meta>,导致viewport-fit=cover实际丢失;微信内置浏览器(X5 内核)多数版本无视该属性,env()值永远是0px - 真机调试时,直接在 Safari 开发者工具控制台运行
getComputedStyle(document.body).getPropertyValue('padding-bottom'),看返回是否是类似"34px"的数字,而不是空字符串或 fallback 值
@supports 检测必须写对语法,否则整块规则被丢弃
@supports 不是查函数是否存在,而是检测该 CSS 声明能否被浏览器识别为合法值。写错就等于没写。
- ✅ 正确:
@supports (padding-bottom: env(safe-area-inset-bottom)) { .tabbar { padding-bottom: env(safe-area-inset-bottom); } } - ❌ 错误:
@supports (env(safe-area-inset-bottom)) { ... }(语法非法,整个@supports块被忽略) - ❌ 错误:
@supports (safe-area-inset-bottom: 34px) { ... }(这不是标准 CSS 属性,检测无效) - fallback 值别设
0,推荐20px或34px:直屏设备也适用,不会因多出空白破坏布局
fixed 元素被遮挡?别只改 padding
padding-bottom: env(safe-area-inset-bottom) 对 position: fixed 的底部按钮完全无效——因为 fixed 元素脱离文档流,padding 动不了它的位置。
- 正确做法是控制定位偏移:
.tabbar { position: fixed; bottom: 0; bottom: env(safe-area-inset-bottom); }(注意单位不能省,env()返回的是带单位的值) - 更现代写法:
inset: auto 0 env(safe-area-inset-bottom) 0;,兼容性略好于重复写bottom - 别在 React/Vue 的
style={{ bottom: 'env(safe-area-inset-bottom)' }}里硬塞——JS 不解析 CSS 函数,只会当字符串透传,最终变成无效样式 - 如果用了
z-index分层,确保该元素层级高于系统 UI(如 Safari 地址栏),否则仍可能被盖住
安卓和微信小程序不能依赖 env() 做跨平台适配
env(safe-area-inset-*) 在绝大多数 Android 设备上根本不会生效。Android Chrome(非 WebView)即使加了 viewport-fit=cover,env() 依然不识别;微信 X5 内核也不支持。
- iOS Safari 和 iOS Chrome(基于 WebKit)可用,但必须三者齐备:
viewport-fit=cover+@supports+ 合理 fallback - uni-app 或小程序中,建议 fallback 方案用动态机型判断:
wx.getSystemInfo获取model,匹配'iPhone X'、'iPhone 12'等关键词后设置固定margin-bottom: 68rpx - 别在
height: 100vh容器内叠加padding-bottom:100vh 本身已包含安全区域外的高度,再加 padding 容易撑出滚动条或留白
真正难搞的不是顶部刘海,而是底部 Home Indicator —— 它会动态变化(比如 Safari 地址栏收起时,env(safe-area-inset-bottom) 可能从 34px 变成 0px),所以 fallback 值必须保守,且逻辑要覆盖状态切换场景。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











