必须加viewport-fit=cover,否则env(safe-area-inset-bottom)恒为0;需在meta中声明并与width=device-width、initial-scale=1.0共存,padding-bottom须作用于底部导航栏自身容器,且需fallback值确保兼容。

viewport-fit=cover 必须加,否则 env() 值恒为 0
不加 viewport-fit=cover,env(safe-area-inset-bottom) 在 iOS Safari 中永远返回 0px——你写的 padding-bottom: env(safe-area-inset-bottom) 就等于没写。它不是可选配置,是启用安全区变量的开关。
必须和 width=device-width、initial-scale=1.0 同时出现在 <meta name="viewport"> 的 content 属性里,用英文逗号分隔:
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
-
viewport-fit=contain是默认行为,会强制内容缩在安全区内,底部留黑边 -
viewport-fit=auto已废弃,设了也无效 - 微信 iOS 客户端(尤其 8.0.32 之前)可能忽略该 meta,需 JS fallback 检测
padding-bottom: env(safe-area-inset-bottom) 加在哪?
不是加在 <body> 上,也不是给父容器设 bottom,而是直接加在底部导航栏自身容器上——目标是让栏内按钮“撑高”,而不是把整个栏往下推。
典型写法:
立即学习“前端免费学习笔记(深入)”;
footer-nav {<br> position: fixed;<br> bottom: 0;<br> width: 100%;<br> height: 60px;<br> padding-bottom: env(safe-area-inset-bottom);<br>}
- 必须配合
height或min-height,只靠padding容易导致高度塌陷 -
bottom: env(safe-area-inset-bottom)是无效写法,Safari 会静默丢弃整条声明 - 如果需要额外留白(比如 8px),低版本 Safari(15.4 之前)不支持
calc(8px + env(safe-area-inset-bottom)),得拆成两行:padding-bottom: 8px和padding-bottom: calc(8px + env(safe-area-inset-bottom))
主体内容怎么避免被底部栏遮住?
fixed 元素脱离文档流,主体滚动时会从它底下穿过去。光靠固定定位不够,必须给主体区域预留空间。
推荐做法:给主内容容器加 padding-bottom,值至少等于底部栏高度 + 安全区:
main-content {<br> padding-bottom: calc(60px + env(safe-area-inset-bottom));<br>}
- 别用
margin-bottom,部分安卓 WebView 对 fixed 元素的 margin 计算不一致 - DOM 结构上,底部栏必须是
<body>的最后一个子元素,否则某些安卓 WebView 可能因父容器overflow: hidden导致渲染异常 - 绝对不要在
<body>上设overflow: hidden,否则 iOS 键盘弹出时 fixed 元素会被裁剪
兼容 fallback 怎么写才靠谱?
env() 在旧版 Safari 或非 iOS 环境中返回 0px,但若没提供 fallback,整条 CSS 声明会被浏览器忽略——所以必须带默认值。
正确写法:
footer-nav {<br> padding-bottom: env(safe-area-inset-bottom, 0px);<br>}
-
constant()已弃用,仅作历史兼容,不要新项目里用 - 渐进增强建议搭配
@supports (padding-top: env(safe-area-inset-top))包裹关键适配逻辑 - 微信 iOS 客户端检测可结合 UA 字符串或运行时
window.innerHeight异常偏小来 fallback 到固定值(如padding-bottom: 34px)
真正起作用的是三者联动:viewport-fit=cover → 开启变量,env() → 获取尺寸,CSS 实际应用 → 避开物理遮挡。漏掉任意一环,Home Indicator 就还在吃你的按钮。



















