必须组合CSS环境变量、布局重构和JS事件监听三类手段:iOS用env(keyboard-inset-bottom)加@supports包裹并设fallback;安卓推荐position:sticky;根容器用flex+100dvh;JS需监听focusin/blur并延迟获取坐标。

不能只靠 bottom: 0 + position: fixed,这是浏览器把 fixed 锚定在「视觉视口(visual viewport)」导致的机制性失效,不是写法错误。必须组合 CSS 环境变量、布局重构和 JS 事件监听三类手段,缺一不可。
用 env(keyboard-inset-bottom) 做 iOS 原生避让(16.4+)
这是目前最干净的纯 CSS 解法,键盘弹出时自动注入当前高度,无需 JS 干预:
- 必须在
中启用适配: - 写法必须带 fallback:
bottom: env(keyboard-inset-bottom, 0px),不能只写env(keyboard-inset-bottom),否则键盘收起后按钮悬空 - 必须用
@supports包裹,否则旧版 Safari(如 15.3)会忽略整条规则甚至解析失败:@supports (bottom: env(keyboard-inset-bottom)) { .btn-footer { bottom: env(keyboard-inset-bottom, 0px); } } - 安卓 WebView 完全不支持,不能单独依赖;也别和
svh或safe-area-inset-bottom混用——语义不同,无效
改用 position: sticky 替代 fixed(推荐首选)
副作用最少、兼容性最好,适合底部按钮紧贴内容流末端的场景(如聊天输入框下方、评论提交区):
- 设
position: sticky; bottom: 0;,父容器需有明确高度约束,例如min-height: 100vh或min-height: 100dvh - 父容器必须允许内部滚动(如
overflow-y: auto),否则sticky不会生效 - 它不脱离文档流,不会被键盘“悬空”顶起,也不受
transform触发的层叠上下文干扰 - 别在 flex 容器里对子元素设
align-self: flex-end来模拟 sticky——那只是视觉错觉,仍可能被顶起
用 flex 布局把“固定”效果做进文档流
彻底绕开视口锚定问题,让底部元素随容器自然排布:
- 根容器(如
#app)设display: flex; flex-direction: column; min-height: 100dvh;(优先用dvh,fallback 可加 JS 判断) - 主内容区设
flex: 1;或margin-top: auto;,底部栏作为同级兄弟节点普通块级元素 - 底部栏不能是
position: fixed,否则仍会被顶;也不能套在 flex 子项内部再设align-self - 避免直接在
body上设height: 100vh——iOS 地址栏会干扰,100dvh更准,但老浏览器需降级为min-height: 100vh+ JS 补偿
JS 动态 fallback:监听 focusin/blur + visualViewport
当以上 CSS 方案都不可用(如老 iOS 或安卓 WebView),这是必做的兜底逻辑:
- 监听所有可聚焦元素:
input、textarea、[contenteditable],漏掉textarea就等于漏掉一半场景 -
focusin回调里必须加setTimeout(() => {}, 0),否则getBoundingClientRect()返回的是键盘弹出前的旧坐标 - 计算
bottom值用window.innerHeight - inputRect.bottom,不是写死数值 -
blur后立刻恢复position: fixed和原始bottom: 0,并调用el.style.removeProperty('top')和el.style.removeProperty('bottom')清除内联样式 - 别依赖
window.addEventListener('resize'):iOS Safari 15.4+ 触发率低于 20%,安卓延迟严重,且常只在键盘收起时触发一次
最容易被忽略的底层细节:iOS 键盘收起后 window.innerHeight 不立即恢复、focusin 触发早于键盘完全展开、Safari 对 window.scrollTo() 有节流策略——这意味着延迟读取、阈值判断(比如下降 >150px 才认为是键盘)、手动锚点恢复不是可选项,是必做动作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











