env(safe-area-inset-bottom)总返回0px是因为iOS Safari默认viewport-fit=auto,未启用安全区API;必须在<head>中声明viewport-fit=cover,且padding-bottom需作用于主内容容器(如#app或main),并配合constant()/env()降级写法及box-sizing: border-box。

为什么 env(safe-area-inset-bottom) 总是返回 0px
不是 CSS 写错了,是浏览器压根没启用安全区 API。iOS Safari 默认用 viewport-fit=auto(等价于 contain),此时所有 safe-area-inset-* 变量都恒为 0px。
必须在 <head> 中显式声明:<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">。
漏掉 viewport-fit=cover,哪怕其他代码全对,env(safe-area-inset-bottom) 就永远是 0px。
部分构建工具(如 Vite 插件)会自动注入 <meta> 标签,但可能覆盖或忽略 viewport-fit —— 务必检查最终 HTML 源码。
padding-bottom 该加在哪个元素上
别加在 body 或 html 上,否则整个页面下移,顶部状态栏区域也可能错位。
正确位置是主内容容器,比如 #app、main 或包裹全部业务内容的最外层 <div>。
这个容器必须是 position: relative 或默认文档流,且设 box-sizing: border-box,否则 padding-bottom 会让总高度超出预期。
值要匹配底部导航栏实际高度(含 padding、border,不含 margin);若导航栏高 60px,就写 padding-bottom: 60px,再叠加安全区。
如何写兼容 iOS 11.0–11.2 的降级样式
旧版 Safari 不支持 env(),只认已废弃但可用的 constant()。
必须按顺序写:padding-bottom: constant(safe-area-inset-bottom); 在前,padding-bottom: env(safe-area-inset-bottom); 在后 —— 顺序反了,iOS 11.2 以下直接忽略整条规则。
如果还要叠加固定高度(比如导航栏本身 60px + 8px 间隔),旧版不支持 calc(60px + env(safe-area-inset-bottom)),得拆成两行:padding-bottom: 60px;padding-bottom: calc(60px + env(safe-area-inset-bottom));
注意:不能写 bottom: env(safe-area-inset-bottom) —— env() 只对 padding 和 margin 有效,用于定位属性会被整条丢弃。
软键盘弹出后底部留白过大怎么办
CSS 无解。iOS Safari 和微信 WebView 的 env(safe-area-inset-bottom) 在软键盘弹出时不会更新,但视口高度会缩,导致原本预留的 padding-bottom 过大,内容被顶到屏幕中间。
这是已知限制,不是你漏写了什么。
可靠方案是监听 focusin/blur 事件,在输入框聚焦时临时移除 padding-bottom,失焦时恢复;更健壮的做法是监听 visualViewport 的 resize 事件动态调整。
真机测试时一定要打开软键盘反复验证 —— 模拟器常无法复现该问题。
立即学习“前端免费学习笔记(深入)”;


















