移动端 fixed 导航被软键盘顶起的本质是视口高度收缩导致定位异常,解决思路是避开键盘区域或改用稳定定位;优先使用 env(safe-area-inset-bottom) 并配合 viewport-fit=cover 实现动态适配。
移动端 fixed 导航在输入框获得焦点、软键盘弹出时被顶起,本质是浏览器视口高度动态收缩导致 fixed 元素仍按原始 viewport 高度定位,而实际可视区域变小。解决核心思路是:让导航避开键盘区域,或改用更稳定的定位策略。
现代 iOS 和部分安卓浏览器支持 env(safe-area-inset-bottom),它不仅能响应刘海/圆角,也能在软键盘弹出时自动更新为键盘高度(需开启 viewport 配置)。关键前提是:
必须包含 viewport-fit=cover,例如:padding-bottom 或 bottom 动态预留空间:env() 虽好,但部分安卓机型(尤其 WebView 或旧版 Chrome)对键盘弹出不更新 safe-area-inset-bottom。此时可结合事件监听做兜底:
focusin(非 focus,因 focus 可能不冒泡)到 input/textarea,获取当前 window.innerHeight;keyboard-active;对于底部导航栏,sticky 比 fixed 更可靠——它依赖父容器流式布局,不会脱离文档流,也不受软键盘缩 viewport 的干扰:
min-height: 100vh),且导航位于容器底部;overflow-y: auto 到 body 或主容器;e
nv(safe-area-inset-bottom) 同样生效:很多问题源于写法本身不合理:
html, body { height: 100vh; } 在键盘弹出时会“假性撑高”,导致 fixed 元素错位;min-height: 100vh 替代 height: 100vh;height: 100vh 或 top: 0; bottom: 0 这类全屏拉伸写法。基本上就这些。env(safe-area-inset-bottom) 是标准解法,sticky 是更普适的降级选择,两者结合覆盖绝大多数场景。不需要 hack,也不必引入第三方库。