viewport-fit=cover是启用env(safe-area-inset-*)的前提,必须写在meta标签中且不可省略;ios需constant()与env()并列降级,安卓不支持该变量,应采用js等替代方案。

不加 viewport-fit=cover,env(safe-area-inset-*) 在 iOS 上压根不会返回有效值,所有 padding 或 fixed 适配都白搭。
viewport-fit=cover 是硬性前提,不是可选项
iOS 11+ 默认把网页限制在安全区域内(等效 viewport-fit=auto),顶部留白、底部被 Home Indicator 遮挡。只有显式声明 viewport-fit=cover,系统才会注入 env(safe-area-inset-*) 变量。
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">必须完整写,漏掉width=device-width或initial-scale=1.0可能导致缩放异常或横屏错位 - 安卓 WebView 大多忽略
viewport-fit,但加了无副作用;别指望它在 Pixel 或旧版 MIUI 上触发安全区变量 - 用 Safari 开发者工具检查:Elements → Computed → 搜索
env(safe-area-inset-bottom),没值就说明 meta 没生效或设备不支持
padding 写法必须带单位 fallback,且 env() 要放在 constant() 后面
env() 在 iOS 11.2+ 才成为标准,而 iOS 11.0–11.1 只认 constant()。只写一个,老设备直接失效;顺序反了,新系统可能覆盖失败。
- 正确写法是两行并列,
env()放后面:padding-top: constant(safe-area-inset-top);<br>padding-top: env(safe-area-inset-top, 0px);
- fallback 值必须带单位,
env(safe-area-inset-top, 0)无效,浏览器会跳过整条声明 - 不要给
height: 100vh的容器只加padding-bottom:100vh 已含刘海高度,再加 padding 会造成双倍下推,内容被顶出视口
fixed 元素被遮挡?不能只靠 body padding
position: fixed; bottom: 0 的导航栏,加 body { padding-bottom: env(...) } 完全没用——padding 影响的是文档流,对 fixed 元素的定位无影响。
- 必须直接作用于该元素:
.fixed-bottom-nav {<br> bottom: env(safe-area-inset-bottom, 0px);<br>} - 如果页面已有固定 header,优先给 header 内部内容加
padding-top,而不是整个body,否则滚动时可能产生视觉错位 - 状态栏下的 fixed 导航栏被裁切?改
top: 0为top: env(safe-area-inset-top, 0px),不是加 margin 或 transform
安卓设备别依赖 env(),降级方案要实际可行
绝大多数安卓机型(华为、小米、OPPO、vivo)不支持 env(safe-area-inset-*),连 Samsung One UI 3.1+ 也仅部分 WebView 场景可用。硬写进去不会报错,但也不会生效。
- 保留
constant()+env()写法无害,但别把它当安卓解决方案 - 真要处理安卓底部导航栏,用 JS 粗略判断更可靠:
window.visualViewport?.height 或 UA 匹配 <code>Android+Mobile,再注入padding-bottom: 48px或64px - 圆角和刘海本身无法用 CSS 精确检测,所谓“媒体查询匹配 iPhone 12/13/14 尺寸”只是历史经验,灵动岛、折叠屏、新挖孔已让这套逻辑失效
真正容易被忽略的点是:安全区变量不是“检测刘海”,而是“声明边界”。你加的每一份 padding 或 bottom,都是在告诉浏览器“这里不准放可操作内容”,而不是在修复某个 bug。一旦理解这点,就不会纠结“为什么 padding-bottom 没挡住 Home Indicator”——因为没对准元素。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











